1

考虑以下:

public class Doer {
   public static void doStuff(A a) {
       System.out.println("a");
   }
   public static void doStuff(B b) {
    System.out.println("b");
   }
}

其中 B 扩展 A

还有一个像这样的通用类:

public class NewClass<T extends A> {
    public void doSomething(T entity) {
        Doer.doStuff(entity);
    }
}

如果我按如下方式调用此方法,它将打印“a”

new NewClass<B>().doSomething(new B());

如何让它打印“b”?

提前致谢

编辑:一个肮脏的解决方案是改变

Doer.doStuff(entity);

if(entity instanceof B){
    Doer.doStuff((B) entity);
}else {
    Doer.doStuff(entity);
}

但是我正在寻找一个不使用 instanceof 的解决方案,这样当我创建一个扩展 A 的新类时,我不必向 NewClass 添加额外的 if (C intance of A) ...

4

4 回答 4

2

请参阅以下问题以获得答案:Java Generic / Type Dispatch QuestionJava 方法调度如何与泛型和抽象类一起工作?

基本上,您有以下选择:

于 2013-07-26T09:09:46.267 回答
1

Java 不会根据参数类型进行动态绑定。调用的实际方法是在编译时确定的。因此,在泛型类型的情况下,Object将调用具有 as 参数类型的方法。

您可以通过使用 instanceof 检查类型来解决此问题,但处理此问题的纯粹方法是利用多态性并使用Double Dispatch。但这并不总是一种选择,因为它将调用类和参数类紧密耦合在一起。

于 2013-07-26T09:16:59.750 回答
0

我认为在这种情况下,您必须实际确定实体的类型并进行转换,因为您的函数 doSomething 只是推断该实体从 A 继承。基本上您可以这样做:

public void doSomething(T entity) {
    if (entity instanceof B) {
        Doer.doStuff((B) entity);
    }
    else {
        Doer.doStuff(entity);
    }
}
于 2013-07-26T09:10:46.260 回答
0

NewClass 也必须有两种方法,或者您可以执行以下操作:

public class NewClass<T extends A> {
    public void doSomething(T entity) {
        if(entity instanceof B){
            Doer.doStuff((B)entity);
        }else if(entity instanceof A){
            Doer.doStuff((A)entity);
        }
    }
}
于 2013-07-26T08:57:43.333 回答