请考虑以下事项:
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)...
答案 0 :(得分:2)
请参阅以下问题以获取答案:Java Generic / Type Dispatch Question,How does Java method dispatch work with Generics and abstract classes?
基本上,您有以下选择:
doStuff
定义为A
答案 1 :(得分:1)
Java不根据参数类型进行动态绑定。调用的实际方法是在编译时确定的。因此,在泛型类型的情况下,将调用Object
作为参数类型的方法。
您可以通过使用instanceof检查类型来解决此问题,但处理此问题的纯粹方法是利用多态并使用Double Dispatch。但这并不总是一种选择,因为它将你的调用类和你的参数类紧密地结合在一起。
答案 2 :(得分: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);
}
}
}
答案 3 :(得分:0)
我认为在这种情况下,您被迫实际确定实体的类型并将其强制转换,因为您的函数doSomething只是推断实体继承自A. 基本上你可以这样做:
public void doSomething(T entity) {
if (entity instanceof B) {
Doer.doStuff((B) entity);
}
else {
Doer.doStuff(entity);
}
}