为什么我不能用Java做到这一点?
public class TestClass {
public <T extends TestClass> T test(){
return this; // error here
}
}
据我了解,this
始终是扩展TestClass
的某个类的实例,那么为什么编译器不允许上面的代码?即使我将扩展TestClass
,但this
的类型仍然适合extends TestClass
。我收到以下错误:
错误:(4,16)java:不兼容的类型:无法转换TestClass 到T
答案 0 :(得分:5)
假设您有SubTestClass extends TestClass
,然后输入:
TestClass instance = new TestClass();
SubTestClass result = instance.test();
关于您的test()
类的签名是合法的,尽管这是胡扯(1)。编译器将推论T
是类SubTestClass
。然后很明显TestClass
实例不是instanceof SubTestClass
。因此,在合法使用test()
方法的情况下,返回this
可能会导致类型不匹配,而这正是编译器告诉您的。
使用您的test()
签名,就无法返回null
以外的任何内容,因为null
是您可以分配给未知类型变量的唯一值。
让我解释一下最后的要求(在注释中要求):test()
方法的实现必须返回一些与T
类型和具体类型相匹配的值(由调用得出)这种情况无法推断出SubTestClass
的情况-参数或实例字段中没有任何内容可以读取这种情况下返回SubTestClass
的要求。在另一种通话情况下,可能需要返回AnotherSubTestClass
,并且无法从第二种情况中分辨出第一种。
如果您返回this
(使用(T)
进行强制转换以使其通过编译器),则在第一种,第二种或两种情况下都会失败。因此,如果没有很高的失败风险,您将无法做到这一点。
可以成功分配给SubTestClass
和AnotherSubTestClass
变量的唯一值是null
值。因此,这是可以从具有这种签名的方法中安全返回的唯一值。
(1)有一个通用方法,该通用方法无法从参数中推导通用类型,而只能从预期结果类型推导,几乎无法工作-该方法应如何知道调用者的期望?
答案 1 :(得分:-1)
您误会了一些东西
据我了解,
this
永远是某个扩展TestClass的类的实例
那是不对的,this
可以是TestClass
本身的一个实例。这就是编译器损坏的原因。为了解决这个问题,您应该将this
强制转换为T
:
return (T) this;
编辑01:
顺便说一句,如果您想做这样的事情,我还建议您添加这两个选项之一,以防止RuntimeError:
TestClass
设置为抽象类this
不是TestClass
的实例,您可以使用类似以下的方法:this.getClass().equals(TestClass.class)
希望这会有所帮助。
答案 2 :(得分:-1)
“此”表示类“ TestClass”,因为TestClass是T的superClass,superClass无法转换为子类,但是您可以尝试强制类型转换,或将返回类型设置为“ TestClass”。
public <T extends TestClass> T test() {
return (T)this;
}
编辑01: 强制转换错误,可能会导致运行时错误。