我有一个小问题,我想知道为什么会发生这种情况: 我做了这样的类(class):
public class SomeSimpleClass {
//and I had method who returns generic. it can be instance of whatever, and for sure can be casted to U:
public <U>U giveMeSomething(String arg) {
return (U)SomewhereSomething.getValueCastingIsOK(arg);
}
}
然后我像这样使用它:
// give me some number:
Integer number = instanceSomeSimpleClass.giveMeSomething("I want integer value");
或者
String text = instanceSomeSimpleClass.giveMeSomething("I want text now");
一切都很好。来自 SomewhereSomething 的 getValueCastingIsOK 返回我想要的内容,并且我不需要在 GiveMeSomething 上进行类型转换。看起来 U 被关联变量的类型替换了..一切都很酷..
但是然后我创建了一个新类:
public class SomeOtherClass <T extends Something> {
//And I have the exactly same method here:
public <U>U giveMeSomething(String arg) {
return (U)SomewhereSomething.getValueCastingIsOK(arg);
}
}
现在,当我想以同样的方式使用它时,编译器(我使用的是 Java 1.7)告诉我,我必须使用类型转换,并开始像这样使用 GiveMeSomething,因为 U 现在是对象,仅此而已...
Integer number = (Integer)instanceSomeSimpleClass.giveMeSomething("I want integer value");
:(
为什么在第二种情况下编译器无法像第一种情况那样以相同的方式获取 U 类型。我必须做什么才能变成这样?
感谢您的回答、建议..;)
最佳答案
问题是您使用的是 SomeOtherClass
类的原始类型,但未向声明提供任何类型参数:
SomeOtherClass instanceSomeSimpleClass = new SomeOtherClass();
当您执行此操作时,Java 编译器将用类型删除版本替换类中的所有泛型,甚至是不相关的泛型(例如泛型方法)。方法的类型删除
public <U>U giveMeSomething(String arg) {
变成了
public Object giveMeSomething(String arg) {
这需要转换为Integer
。
您必须向 SomeOtherClass
提供类型参数(无用,除非您已经消除了使用 T
在此处发布类代码的不必要代码):
SomeOtherClass<Something> instanceSomeSimpleClass = new SomeOtherClass<Something>();
或者您可以删除类定义中的类型参数,就像最初那样:
public class SomeSimpleClass {
这两种方法都会保持泛型方法的完整性,并且无需转换 giveMeSomething
的返回类型。
关于java 类声明,其中泛型类型禁用方法返回另一个泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20573531/