我正在练习仿制药,我做了以下工作。
创建了一个名为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>
感到困惑?
答案 0 :(得分:1)
好的,你在那里有四个不同的问题,但我会试一试!
现在我将班级签名更改为
public class Person<T extends Man>{}
我再也无法创建一个字符串类型的人。为什么会这样?
因为通过编写Person<T extends Man>
,您指定人员的类型参数T
必须扩展Man
(这也允许它为Man
)。因此,如果Milkman
和Postman
都延伸Man
,则Person<Milkman>
,Person<Postman>
和Person<Man>
都是有效类型,但{{1} }不是,因为Person<String>
不会延伸String
。
Man
为什么编译器只对人在人感到困惑?
因为在此声明中,您使用public class Person<Man> extends AliveBeing<Man>{}
的方式与大多数人使用Man
或T
的方式相同 - 也就是说,它是类型参数,而不是实际的类。您正在创建一个通用E
类,其中Person
可以替换为任何类型。
编译器警告说,通过执行此操作,您将屏蔽类Man
的实际定义,该类现在无法在Man
泛型类定义中使用。这几乎肯定不是你打算做的,这就是编译器警告你的原因。