Java中的重载/泛型

Ixx*_*Ixx 10 java generics

我想在列表中运行某些测试.列表可以包含完全不同的类.

我有一种方法来检查列表的一致性 - 不是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)......"

那么有什么优雅的解决方案吗?我可以使用不同的方法名称,但想知道没有它的可能性.

谢谢!

Mar*_*ers 10

这不是你遗漏的泛型.Java没有双重调度.因此,要求check必须在编译时解决,check(T)是因为编译器不能告诉我们,如果只匹配TSomeTypeSomeOtherType在一个给定的情景.它需要选择一种可以适用于所有可能T的方法.

有时使用访客模式解决这个问题.


Mis*_*ble 1

由于变量的类型丢失,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)

这是仅有的两个选项,任何实现都必须是其中之一的变体