将通用参数约束为Java中的不同类型

时间:2019-05-12 11:41:17

标签: java polymorphism abstract-class abstraction

我不记得它的正确名称,这就是为什么我无法使用它,所以我将通过一个示例来询问它,以便它立即响起铃响。

这是针对Java的。

我正在使用带有受限类型参数的抽象类和接口,就像这样:

public interface DBInterface<T, E> {
    public int delete(T element);
}

我的问题是,当我尝试重载这样的函数时:

public interface DBInterface<T, E> {
    public int delete(T element);
    public int delete(E example);
}

IDE抱怨T可能与E相同,因此它认为我两次声明了完全相同的方法(因为实际上,该声明中T可能与E相同)。

我的问题是:

  1. 这怎么称呼?我想使用适当的术语重写问题,以便将来对其他人变得更有用
  2. 如何在界面中删除T和E以确保它们不是同一类型?

类似这样的东西:

public interface DBInterface<T, E != T> {
    public int delete(T element);
}

我现在做的方式是通过这样的合法类型定界。这是正确的方法吗?有没有一种方法可以允许除提供的另一个对象之外的任何对象?:

public interface DBInterface<T extends DatabaseObject, E> {
}

1 个答案:

答案 0 :(得分:2)

存在一个问题,因为编译器必须为您的方法使用参数化类型的擦除。由于TE没有进入运行时,因此编译器会系统地替换您的方法参数类型。

根据本教程(请检查thisthis),将无界类型参数替换为Object,并对有界类型参数强制执行边界。 就是说您编译的接口方法签名如下:

public interface DBInterface {
    public int delete(Object element);
    public int delete(Object example);
}

第二个版本:

public interface DBInterface<T extends DatabaseObject, E> {
    public int delete(DatabaseObject element);
    public int delete(Object example);
}

我相信这对于您的第一个代码段来说是很明显的问题。

  

如何在接口中声明T和E以确保它们不是同一类型?

该问题不能接受不合格的答案。实际答案取决于TE的含义。例如,建议这些类型参数的边界不同是没有意义的,因为在某些情况下这可能没有意义。

话虽如此,您应该考虑的一件事是重命名方法:我想不出带有两个相似类型的参数且没有扮演不同角色的DBInterface。例如,方法可以是:

public int deleteById(T element);
public int deleteByKey(E key);

换句话说,如果我们忘记了单字母通用类型名称约定,那么您将如何命名类型参数?

public interface DBInterface<IdColumnType, PKColumnType> {}

我不明白为什么不应该将此方法应用于您的方法名称,您必须承认,您毕竟已经允许用户为两个类型参数传递相同的类……(也就是说即使编译器没有进行类型擦除,从技术上讲您仍然会遇到问题)