为什么我们不能通过通用类型T而不是?在泛型

时间:2017-04-30 06:08:57

标签: java generics wildcard

我有一个Animal类和一个扩展Animal的Cat类(Cat is a Animal) 我已经定义了一个泛型类:

public class Employee<T extends Animal> {
    T obj;
    Employee(T o){
        obj=o;
    }
    String getName(Employee<T> a){
        return "ok";
    }
}

在测试类中,如果我写这个,它会给我以下错误错误:

Employee<Cat> cat = new Employee<Cat>(null);
Employee<Animal> animal = new Employee<Animal>(null);
animal.getName(cat);

但是如果我给getName方法传递问号,它可以工作,我认为Cat是一个动物(Cat类扩展Animal)。知道为什么我需要通过吗?而不是T?

2 个答案:

答案 0 :(得分:2)

如果你有方法getName(Employee<T> a),那么此方法只接受Employee<T>,在animal.getName(a)的情况下,它意味着它必须是Employee<Animal>(因为{{1}是animal

如果您还想接受泛型类型的子类,则必须说

Employee<Animal>

如果您还想接受泛型类型的超类,则必须说

String getName(Employee<? extends T> a)

如果您实际上并不关心其他动物的通用类型,您可以说

String getName(Employee<? super T> a)

这四种情况中哪一种是合适的取决于方法实际需要做什么(以及两种对象及其他方法如何使用泛型类型)。

答案 1 :(得分:1)

虽然CatAnimal兼容,但Employee<Cat>Employee<Animal>不兼容。它们是完全不同的类型。或者更常见的是,即使A<T>A<U>兼容,T也与U不兼容。

<?><T>之间的区别是什么?

<T>中,您有一个泛型类型参数T,在本例中为Animal。因此,该方法接受类型Employee<Animal>.的参数正如我所说的,在Employee<Cat>中放置Employee<Animal>只是不起作用,这就是代码无法编译的原因。

另一方面,

<?>允许将任何内容放入括号中,无论是CatDogTigerUnicorn,等等

P.S。为什么Employee的字段为Animal?那有点奇怪......只是说......