类型参数E隐藏了类型E.尝试了不同的变化,仍然无法修复

时间:2013-11-06 20:27:55

标签: java generics types

我正在练习仿制药,我做了以下工作。

创建了一个名为man的类,如下所示。

public class Man {
    int hands=2;
    int legs=2;
    boolean alive;

    public Man(boolean b) {
        // TODO Auto-generated constructor stub
        alive=b;
    }
}

创建了一个名为person的类

public class Person<Man> {
    Man p;
    String name;


    public Person(Man p, String name) {
        this.p = p;
        this.name = name;
    }

    public Person() {
        // TODO Auto-generated constructor stub
    }

}

试图像下面那样实例化String或int类型的人,但它没有抛出错误。

Person<String> p1 = new Person<String>(new String("test"), "test1");
Person<Integer> p2=new Person<>(1,"test");

现在我将班级签名更改为

 public class Person<T extends Man>{} 

我再也无法创建String类型的人了。为什么会这样?我希望人类严格地成为一个人,而不是一个人的子类的突变体。我该怎么做?

我甚至尝试过以下

public abstract class AliveBeing<T>{}

让AliveBeing成为Man的超类,然后尝试

public class Person<Man> extends AliveBeing<Man>{}

即使是现在,Man中的Person<Man>下面还有黄线(类型参数Man隐藏类型Man),而AliveBeing中的Man则没有。

为什么编译器只对Man中的Person<Man>感到困惑?

1 个答案:

答案 0 :(得分:1)

好的,你在那里有四个不同的问题,但我会试一试!

  

现在我将班级签名更改为

     

public class Person<T extends Man>{}

     

我再也无法创建一个字符串类型的人。为什么会这样?

因为通过编写Person<T extends Man>,您指定人员的类型参数T必须扩展Man(这也允许它为Man)。因此,如果MilkmanPostman都延伸Man,则Person<Milkman>Person<Postman>Person<Man>都是有效类型,但{{1} }不是,因为Person<String>不会延伸String

  

Man

     

为什么编译器只对人在人感到困惑?

因为在此声明中,您使用public class Person<Man> extends AliveBeing<Man>{}的方式与大多数人使用ManT的方式相同 - 也就是说,它是类型参数,而不是实际的类。您正在创建一个通用E类,其中Person可以替换为任何类型。

编译器警告说,通过执行此操作,您将屏蔽类Man的实际定义,该类现在无法在Man泛型类定义中使用。这几乎肯定不是你打算做的,这就是编译器警告你的原因。