0

昨天看到这个帖子:我如何实例化?包含代码

用户无法获取泛型类的构造函数类型 X 以匹配传递给构造函数 IA 的对象类型,即使<X extends IA>.

我真的不喜欢提供的唯一答案,因为如果您必须将 M 构造函数类型从Xto更改,它会使泛型的全部意义变得无用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,包括“扩展”

4

3 回答 3

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 < ASpecificType > 可以获得的类型安全性,编译器会引起你的注意。

以下代码是我可以得到的最接近您的代码的代码,同时也具有一定的意义:

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
}
于 2012-07-13T12:56:11.797 回答
1

这个问题涉及许多没有意义的通用约束。M<X>的构造函数接受 type 的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);
}
于 2012-07-13T19:52:38.797 回答
0

问题是传入构造函数的 a 是 IA 类型。M 的构造函数需要 X。IA 不能强制转换为 X,因此这是一个语法错误。

第二个选项确实可以编译,但是如果您要实际运行它,您会将 amx 分配给一个实际上不是 X 实例的变量(因此您收到警告说这是一个坏主意的原因)。

如果您更改构造函数以接受 IA,那么一切正常。

于 2012-07-13T13:06:43.310 回答