泛型中的通配符:"?超级T”工作时 "?延伸T”不?

发布于 2024-12-06 03:08:30 字数 1281 浏览 0 评论 0 原文

我的问题是关于Java 7中的泛型。假设我们有这样的类层次结构:

interface Animal {}    
class Lion implements Animal {}    
class Butterfly implements Animal {}

就像 Java 泛型教程

我们还有一个类

class Cage<T> {
    private List<T> arr = new ArrayList<>();
    public void add(T t) {
        arr.add(t);
    }
    public T get() {
        return arr.get(0);
    }
}

,这里​​是使用该类的代码:

public static void main(String[] args) {
        Cage<? extends Animal> cage = new Cage<>();
        Animal a = cage.get(); //OK
        cage.add(new Lion()); //Compile-time error
        cage.add(new Butterfly()); //Compile-time error   
    }

问题 #1:

我已阅读 此处介绍了这些问题,但就像 Cage ;。但我告诉编译器 ,因此 Cage 中的 T 类型将是 Animal 类型的任何子类型。那么为什么它仍然给出编译时错误呢?

问题#2:

如果我指定Cage<?超级动物>笼=...而不是Cage<?延伸动物> age = ... 一切正常,编译器没有说任何不好的事情。为什么在这种情况下它工作得很好,而在上面的例子中却失败了?

My question is about generics in Java 7. Suppose we have such class hierarchy:

interface Animal {}    
class Lion implements Animal {}    
class Butterfly implements Animal {}

Just like in Java Generics Tutorial

Also we have a class

class Cage<T> {
    private List<T> arr = new ArrayList<>();
    public void add(T t) {
        arr.add(t);
    }
    public T get() {
        return arr.get(0);
    }
}

And here is the code which uses that classes:

public static void main(String[] args) {
        Cage<? extends Animal> cage = new Cage<>();
        Animal a = cage.get(); //OK
        cage.add(new Lion()); //Compile-time error
        cage.add(new Butterfly()); //Compile-time error   
    }

Question #1:

I have read here about these issues but there was simply like Cage<?>. But I tell the compiler <? extends Animal> so type T in Cage<T> will be any of subtypes of Animal type. So why it still gives a compile time error?

Question #2:

If I specify Cage<? super Animal> cage = ... instead of Cage<? extends Animal> cage = ... everything works fine and compiler doesn't say anything bad. Why in this case it works fine while in the example above it fails?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城花音 2024-12-13 03:08:30

笼子必须能够容纳两种类型的动物。 “super”表示 - 它表示笼子必须能够容纳所有类型的动物 - 也许还可以容纳其他一些东西,因为? super Animal 可能是 Animal 的超类。 “extends”表示它可以容纳某些种动物 - 例如,也许只是狮子,如下所示:

Cage<? extends Animal> cage = new Cage<Lion>();

这将是一个有效的陈述,但显然狮子笼不能容纳蝴蝶,所以

cage.add(new Butterfly());   

不会不编译。该语句

cage.add(new Lion());

也不会编译,因为 Java 正在查看笼子的声明 - Cage - 不是现在分配给它的对象 (Cage)。

我所知道的对泛型最好的描述是O'Reilly 的 Java in a Nutshell。本章免费在线 - 第 1 部分第 2 部分

The cage must be able to hold both types of animals. "super" says that - it says that the Cage must be able to hold all types of animals - and maybe some other things, too, because ? super Animal might be a superclass of Animal. "extends" says that it can hold some kinds of animals - maybe just Lions, for instance, as in:

Cage<? extends Animal> cage = new Cage<Lion>();

which would be a valid statement, but obviously the lion cage won't hold butterflies, so

cage.add(new Butterfly());   

wouldn't compile. The statement

cage.add(new Lion());

wouldn't compile either, because Java here is looking at the declaration of the cage - Cage<? extends Animal> - not the object that's assigned to it right now (Cage<Lion>).

The best description of generics I know of is in O'Reilly's Java in a Nutshell. The chapter is free online - part 1 and part 2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文