我正在尝试Java泛型。我了解使用Java泛型,我们可以创建仅处理特定类型的类和方法。这样可以在编译时检测编程错误。

我的问题听起来很奇怪。为什么要使用E extends Superclass而不是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 AnimalAnimal几乎相同,只是第一个可能提供更多信息。任何想法?

最佳答案

实际上,在Animal类的定义中声明的Keaper不过是一个类型参数(通常只使用一个字母,例如Keaper<T>)。因此,可能的类型参数的范围完全不同:Keaper类可以接受任何类型作为参数,而不仅仅是Animal。您可以编写Keaper<String>,它将编译良好,这显然不是您想要的。

泛型无法实现您打算做的事情:您不能强制一个类仅具有一个可能与类型关联的类型实参。您可以做的是将关联类型的范围限制为例如任何扩展了某种类型的类型(您已经使用Hunter类进行了此操作)。

同样,如@JHH的注释中所述,您应该避免将Keaper用作列表中的原始类型,否则该代码将不是完全通用的。除了ArrayList<Keaper> keapers = new ArrayList<>()之外,您还可以编写ArrayList<Keaper<? extends Animal>> keapers = new ArrayList<>()

关于java - 通用: why use “class A <E extends Superclass>” in stead of “class B<Superclass>” ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35973304/

10-13 07:31