我想在列表中运行某些测试.列表可以包含完全不同的类.
我有一种方法来检查列表的一致性 - 不是null,不是空,不是x元素.这对所有列表都是通用的.然后我想使用重载来测试每个对象.
这个想法是这样的:
public static <T> void check(List<T> list) {
//do general checks
for (T element : list) {
check(element);
}
}
Run Code Online (Sandbox Code Playgroud)
然后
public static void check(SomeType element) {...}
public static void check(SomeOtherType element) {...}
Run Code Online (Sandbox Code Playgroud)
但我还必须添加这样的方法:
public static void check(T element) {...}
Run Code Online (Sandbox Code Playgroud)
这是在运行时调用的 - 而不是我使用特定类的其他方法.虽然班级完全相同.我显然错过了一些泛型的理解.
现在,如果我根本不使用通用方法并尝试以这种方式解决它:
public static void check(List<SomeType> list) {...}
public static void check(List<SomeOtherType> list) {...}
Run Code Online (Sandbox Code Playgroud)
编译器错误 - "方法检查(List)与另一种方法具有相同的擦除检查(List)......"
那么有什么优雅的解决方案吗?我可以使用不同的方法名称,但想知道没有它的可能性.
谢谢!
由于变量的类型丢失,check(List<T> list)您有两种选择:
1.通过检查运行时类型来做不同的事情
check(T element) {
if (element.getClass().equals(SomeType.class)) {
check((SomeType) element);
} elseif (element.getClass().equals(SomeOtherType.class)) {
check((SomeOtherType) element);
}
Run Code Online (Sandbox Code Playgroud)
这可以变得更复杂一些,例如通过将每张支票包装在 a 中Callable并使用Map<Class, Callable>
这类似于访客模式。
2. 对要检查的元素本身调用虚方法
如果检查逻辑可以推送到要检查的对象本身(这不一定是坏事),那么您不需要检查类型:
interface Checkable { void check(); }
class SomeType implements Checkable { .... }
class SomeOtherType implements Checkable { .... }
Run Code Online (Sandbox Code Playgroud)
然后:
public static <T extends Checkable> void check(List<T> list) {
for (T element : list) {
element.check();
}
}
Run Code Online (Sandbox Code Playgroud)
这是仅有的两个选项,任何实现都必须是其中之一的变体