我有以下代码让我无法编译。
给我这个错误
Error:(20, 22) java: incompatible types: com.company.Main.Impl cannot be converted to T
我只需要在该函数中使用该接口,并且我不想更改函数体。
为什么这不起作用? 和 我怎么能做这个工作?
package com.company;
public class Main {
class Impl implements someinterface, anotherinterface{
@Override
public Integer getInteger() {
return 0;
}
}
class BigObject{
public Impl get(){
return new Impl();
}
}
private <T extends someinterface & anotherinterface> Integer myfunc(BigObject bg){
T xy = bg.get(); // this line will not compile????
if (xy.isOK()) // from someinterface
return xy.getInteger(); // from anotherinterface
return null;
}
public static void main(String[] args) {
// write your code here
}
}
答案 0 :(得分:2)
它不会编译,因为在Java中,泛型是不变的,see related post。
使用以下代码行:
<T extends SomeInterface> Integer myfunc(BigObject bg) { ... }
你是说T
是某种类SomeInterface
,或者更确切地说,某种类型是SomeInterface
的子类型。编译器抱怨T xy = bg.get()
,因为bg.get()
返回T
的某个子类型,但该类型可能与Impl
相同或不同。
作为类比,你说的是这样的话:
class Cat extends Animal { }
class AnimalObj {
public Cat get() {
return new Cat();
}
}
private <T extends Animal> Integer myfunc(AnimalObj bg) {
T xy = bg.get();
...
}
T
可以是Cat
,但也可以是Dog
。谁知道。这就是编译器抱怨的原因。
如果你不关心子类型,你应该删除泛型,而是写下来:
private Integer myfunc(AnimalObj bg) {
Animal xy = bg.get();
...
}
由于myFunc
接受能够提供具体BigObject
的{{1}},您只需将Impl
替换为<T extends someinterface & anotherinterface>
。
答案 1 :(得分:0)
让我们稍微更改一下myfunc
,以便它返回通用类型T
:
private static <T extends someinterface & anotherinterface> T myfunc(BigObject bg){
return bg.get();
}
现在你可以这样称呼它:
Impl i1 = myfunc( new BigObject() );
并且像这样:
Impl2 i2 = myfunc( new BigObject() );
但是,如果BigObject.get
只返回Impl
,那么预期Impl2
的第二次通话就会出错。