将泛型参数限制为 Java 中的不同类型
Constraining generic parameters to be different types in Java
我不记得它的正确名称,这就是为什么我不能 Google 它,所以我会用一个例子来问这个,所以它会立即响铃。
这是给 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 相同) .
我的问题是:
- 这个怎么称呼?我想使用适当的术语重写问题,以便将来对其他人更有用
- 如何声明接口中的 T 和 E 以保证它们不是同一类型?
像这样:
public interface DBInterface<T, E != T> {
public int delete(T element);
}
我现在的做法是像这样分隔合法类型。这是正确的方法吗?有没有办法允许除提供的另一个对象之外的任何对象?:
public interface DBInterface<T extends DatabaseObject, E> {
}
存在一个问题,因为编译器必须为您的方法使用参数化类型的擦除。由于 T
和 E
没有进入运行时,编译器会以系统的方式替换您的方法参数类型。
根据教程(检查 this and this),无界类型参数被替换为 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);
}
我相信这会使您的第一个代码片段的问题变得显而易见。
How can I declare T and E in the interface to guarantee they will not be the same type?
本题不接受不合格答案。实际答案取决于 T
和 E
的含义。例如,建议对这些类型参数进行不同的限制是没有意义的,因为在某些情况下这可能没有意义。
话虽如此,您应该考虑的一件事是重命名方法:我想不出 DBInterface
具有两个类型相似但作用不同的参数。例如,方法可以是:
public int deleteById(T element);
public int deleteByKey(E key);
换句话说,如果我们忘记 single-letter 泛型类型命名约定,您会如何命名您的类型参数?
public interface DBInterface<IdColumnType, PKColumnType> {}
我不明白为什么这不应该应用于您的方法名称,毕竟您必须承认您已经允许您的用户为两种类型的参数传递相同的 class。 ..(也就是说,即使编译器不进行类型擦除,您在技术上仍然存在问题)
我不记得它的正确名称,这就是为什么我不能 Google 它,所以我会用一个例子来问这个,所以它会立即响铃。
这是给 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 相同) .
我的问题是:
- 这个怎么称呼?我想使用适当的术语重写问题,以便将来对其他人更有用
- 如何声明接口中的 T 和 E 以保证它们不是同一类型?
像这样:
public interface DBInterface<T, E != T> {
public int delete(T element);
}
我现在的做法是像这样分隔合法类型。这是正确的方法吗?有没有办法允许除提供的另一个对象之外的任何对象?:
public interface DBInterface<T extends DatabaseObject, E> {
}
存在一个问题,因为编译器必须为您的方法使用参数化类型的擦除。由于 T
和 E
没有进入运行时,编译器会以系统的方式替换您的方法参数类型。
根据教程(检查 this and this),无界类型参数被替换为 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);
}
我相信这会使您的第一个代码片段的问题变得显而易见。
How can I declare T and E in the interface to guarantee they will not be the same type?
本题不接受不合格答案。实际答案取决于 T
和 E
的含义。例如,建议对这些类型参数进行不同的限制是没有意义的,因为在某些情况下这可能没有意义。
话虽如此,您应该考虑的一件事是重命名方法:我想不出 DBInterface
具有两个类型相似但作用不同的参数。例如,方法可以是:
public int deleteById(T element);
public int deleteByKey(E key);
换句话说,如果我们忘记 single-letter 泛型类型命名约定,您会如何命名您的类型参数?
public interface DBInterface<IdColumnType, PKColumnType> {}
我不明白为什么这不应该应用于您的方法名称,毕竟您必须承认您已经允许您的用户为两种类型的参数传递相同的 class。 ..(也就是说,即使编译器不进行类型擦除,您在技术上仍然存在问题)