昨天看到这篇文章:How I instantiate? Include code
用户无法获取泛型类的构造函数类型X,以匹配传递给构造函数IA的对象的类型,即使<X extends IA>
。
我并不是非常喜欢提供的唯一答案,因为如果你必须将M构造函数类型从X
更改为IA<X>
,那么泛型的全部意义就无济于事。当然这就是为什么M
的泛型类型是<X extends IA>
??
对于这个基本的例子,真的没有办法使用泛型(没有任何被抑制的警告)吗?
public interface IA<X extends IA<X>>{}
public class A<X extends IA<X>> implements IA<X>{}
public class W<X extends IA<X>>{}
public class M<X extends IA<X>> extends W<X>{
X anx;
public M(X x){} //Type X here is not compatibile with IA in the test code
}
//Testing code in a different class
public <X extends IA<X>> void check() {
IA<X> a = new A<X>();
W<X> s = new M<X>(a); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA>
W<X> s = new M(a); //Compiles, but with suppressed warnings
X a = new A<X>(); //Doesnt compiler (ignoring dupicate 'a' variable)
W<X> s = new M<X>(a); compiles
}
编辑以包括IA到处包括'extends'
答案 0 :(得分:2)
你必须做这样的事情:
//Testing code in a different class
public <X extends IA<X>> void check() {
IA<X> a = new A<X>();
W<subtypeofIA(IA works as well)> s = new M<subtypeofIA(IA works as well)>(a); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA>
W<X> s = new M(a); //Compiles, but with suppressed warnings
}
关于警告,我认为它们是不言自明的,它们可以概括为:当你想要使用一般参数化类型时,你必须将泛型参数实例化为具体类型。引入了通用参数以概括代码,但也强制类型安全。使用IA意味着你扔掉了你可以说的类型安全:IA&lt; ASpecificType&gt;并且编译器会引起你的注意。
以下代码是我能够接近您的代码并且同时具有一定意义的代码:
interface IA<X extends IA<X>>{}
class A<X extends IA<X>> implements IA<X>{}
class W<X extends IA<X>>{}
class M<X extends IA<X>> extends W<X>{
X anx;
public M(X x){} //Type X here is not compatibile with IA in the test code
}
//Testing code in a different class
public <X extends IA<X>> void check() {
IA<X> a = new A<X>();
W<X> s = new M<X>(null); //Doesn't compile because IA<X> is not the same as 'X', even though <X extends IA>
W<X> ss = new M(a); //Compiles, but with suppressed warnings
X aa = new A<X>(); //this is completely illegal
W<X> sss = new M<X>(aa); //compiles
}
答案 1 :(得分:1)
这个问题涉及许多没有意义的通用约束。 M<X>
的构造函数接受类型为X
的参数,这是泛型方法check
的类型参数(这意味着调用者可以将X
决定为任何内容需要仍然工作)。那么为什么你期望a
(或其他任何事情)成为正确的类型?
如果你想问一下如何更改泛型约束以使其有效,这里有一个更简单的事情(它只是改变了泛型(但保持W
和M
原样)而没有别的从原始的)编译,并可能更接近你想要的东西:
public interface IA<X>{}
public class A implements IA<A>{}
public class W<X extends IA<X>>{}
public class M<X extends IA<X>> extends W<X>{
X anx;
public M(X x){}
}
public void check() {
A a = new A();
W<A> s = new M<A>(a);
}
答案 2 :(得分:0)
问题是,传递给构造函数的a是IA类型。 M的构造函数需要X. IA不能转换为X,因此这是语法错误。
第二个选项是编译,但是如果你实际运行它,你会将amx分配给一个实际上不是X实例的变量(因此你会得到警告说这是一个坏主意)。
如果你改变构造函数以接受IA,那么一切正常。