我正在试验Java泛型。据我所知,使用Java泛型,我们可以创建只处理特定类型的类和方法。这使得能够在编译时检测编程错误。
我的问题可能听起来很奇怪。为什么不使用Superclass而使用E extends Superclass?请看一下下面的代码。
class Hunter <E extends Animal>{}
class Keaper <Animal>{}
/*edit: as AR.3 and other pointed out, Keaper<Animal> is the same as Keaper<E>.
Animal is just a type parameter here*/
class Animal{}
class Cat extends Animal{}
class Dog extends Animal{}
public class TestGeneric {
public static void main(String[] args) {
Hunter<Cat> hunter1 = new Hunter<>();
Hunter<Dog> hunter2 = new Hunter<>();
Hunter<Animal> hunter3 = new Hunter<>();
ArrayList<Hunter> hunters= new ArrayList<>();
hunters.add(hunter1);
hunters.add(hunter2);
hunters.add(hunter3);
Keaper<Cat> keaper1 = new Keaper<>();
Keaper<Dog> keaper2 = new Keaper<>();
Keaper<Animal> keaper3 = new Keaper<>();
//Edit: as AR.3 and others pointed out, Keaper<String> is also legal here.
ArrayList<Keaper> keapers= new ArrayList<>();
keapers.add(keaper1);
keapers.add(keaper2);
keapers.add(keaper3);
}
}我觉得E extends Animal和Animal几乎是一样的,只是前者提供了更多的信息。有什么想法吗?
发布于 2016-03-14 01:27:41
实际上,在Keaper类的定义中声明的Animal只是一个类型参数(更传统的做法是只使用一个字母,如Keaper<T>)。因此,这是一个完全不同的类型参数范围:Keaper类可以接受任何类型作为参数,而不仅仅是Animal。您可以编写Keaper<String>,它可以很好地编译,这显然不是您想要的。
使用泛型是不可能实现的:您不能强制一个类成为泛型,并且只与一个可能的类型参数相关联。您可以做的是将关联类型的范围限制为,例如,扩展特定类型的任何类型,您已经对Hunter类执行了此操作。
此外,正如@JHH的注释中所提到的,您应该避免在列表中使用Keaper作为原始类型,否则代码将不是完全泛型的。您可以编写ArrayList<Keaper<? extends Animal>> keapers = new ArrayList<>()而不是ArrayList<Keaper> keapers = new ArrayList<>()。
发布于 2016-03-14 01:34:38
通常,当您想要保留特定类型的in参数时,可以使用extends。考虑这个例子:
public class TestGeneric {
public static <T extends Animal> T changeExtendedAnimal(T extendedAnimal) {
return extendedAnimal;
}
public static Animal changeAnimal(Animal animal) {
return animal;
}
public static void main(final String[] args) {
Cat changedCat1 = changeExtendedAnimal(new Cat()); //Compiles fine.
Cat changedCat2 = changeAnimal(new Cat()); //Won't compile: Type mismatch: cannot convert from Animal to Cat
}
}这里的changeExtendedAnimal()方法使用了扩展,因此,如果您使用Cat调用该方法,编译器就会知道您将得到一个Cat。
另一方面,使用changeAnimal()方法,编译器无法知道这一点,因此会得到一个编译时错误。
https://stackoverflow.com/questions/35973304
复制相似问题