我正在尝试Java中的泛型,并想到了这个例子。
如果我有ClassA<T>
,我可以用引用具体类的子类覆盖它,例如ClassB extends ClassA<String>
,然后ClassA使用T,ClassB可以使用String。
现在,忽略之前的ClassA
和ClassB
,如果我有一个抽象的ClassA
,它有一个通用的方法:
public <T> void doSomething(T data);
有没有办法让ClassB
用一个具体的类覆盖它,类似于前面的例子?我想出了一些有用的东西,即参数化类和方法,但我想知道是否还有其他方法。
class ClassA<T> {
public void doSomething(T data) {};
}
我不想将参数放在类中的原因是因为它只有一个方法可以对该类型执行任何操作,而某些子类甚至可能不希望在该方法中执行任何操作,因此我不需要如果它不打算使用它,请在类中放置一个参数。
注意:ClassA
的所有子类都是匿名类,因此增加了乐趣。
答案 0 :(得分:12)
感谢type erasure,这个:
public <T> void doSomething(T data);
真的意思是:
public void doSomething(Object data);
所以不,没有办法用更严格的参数类型覆盖。
也在此代码中:
class ClassA<T> {
public <T> void doSomething(T data) {};
}
类名中的type参数和方法中的type参数实际上是不同的参数。这就像声明一个与更高范围内的变量同名的局部变量。您可以在doSomething(123)
的实例上致电ClassA<String>
,因为第二个T
是该方法的本地。
答案 1 :(得分:2)
简而言之,答案是否定的。如果使用泛型参数定义方法,则其签名包含泛型,并且任何“覆盖”必须与签名匹配(包含泛型)。
无论如何,这对泛型来说真的很糟糕,因为你所写的内容在语义上与
相同public void doSomething(Object data) {}
除非用于表示返回值是什么,否则通用位不会给你带来太大的收益,如:
public <T> T doSomething(T data) {}
但为什么要这么麻烦?是否真的存在调用doSomething()的问题?