Java泛型和集合,为什么我不能实例化具有通配符的新列表?(Java Generics & Collections, why can't I instantiate new List wit

编程入门 行业动态 更新时间:2024-10-07 22:29:16
Java泛型和集合,为什么我不能实例化具有通配符的新列表?(Java Generics & Collections, why can't I instantiate new List with wildcards?)

为什么我可以有一个方法接收带有通配符的列表:

public processGenerics(List<? extends User> users){...}

但我不能以类似的方式实例化相同的列表?

List<? extends User> alist = new ArrayList<? extends User>();

[编辑,而不是原始问题的一部分,但相关]为什么我不能以正常继承的相同方式执行与集合的投射:

List<User> users = new ArrayList<Admin>();

Why can I have a method receiving a list with wildcards:

public processGenerics(List<? extends User> users){...}

but I cannot instantiate that same List in a similar way?

List<? extends User> alist = new ArrayList<? extends User>();

[Edited, not part of the original question, but relevant] Why can't I do casting with Collections the same way of normal inheritance:

List<User> users = new ArrayList<Admin>();

最满意答案

你的问题最令人困惑的方面是你必须经历的泛型类型与经典原始类型的底层心理切换。

在泛型之前,每个变量都有一个明确的类型,比如Object。 虽然你可以给它分配一个字符串,但字符串仍然是一个对象,所以这个范例保留 - 在所有情况下,你都将一个对象分配给一个对象var。

泛型不适用。 你可能有一个List<? extends Number> List<? extends Number> ,它可以从一系列与声明的变量类型没有instanceof关系的类型中分配,但只能满足特定的模式 。 该模式由通配符描述。

所以,当你推理泛型变量类型时,为了让你的生活更轻松,你需要放弃一个明确类型的简单和舒适的概念,并根据这些“类型模式”来思考。

至于问题的第二部分: List<User>和List<Admin>是完全不相关的类型,无论User和Admin是否相关。 这就是泛型的工作原理,这有很好的理由。 Java不允许将OrdinaryUser添加到List<Admin> ,并且在您可能发生的假设下:

List<User> users = new ArrayList<Admin>(); users.add(new OrdinaryUser()); // shouldn't be allowed!

官方的术语是泛型类型对于它们的类型参数是不变的 。 这个词最好是google,因为它已经被很好地覆盖了。

The most confusing aspect of your problem is the underlying mental switch you must undergo with generic types vs. classic raw types.

Before Generics, each variable had a definite type, such as Object. Although you could assign a String into it, a String still is an Object, so the paradigm holds—in all cases you are assigning something that is an Object into an Object var.

Not so with Generics. You may have a List<? extends Number>, which can be assigned from a range of types that have no instanceof relation to the declared variable type, but only satisfy a certain pattern. The pattern is described by the wildcard.

So, to make your life easier when you reason about generic variable types, you need to abandon the simple and cozy notion of a definite type and think in terms of these "type patterns".

As far as the second part of your question: List<User> and List<Admin> are completely unrelated types, regardless of the fact that User and Admin are related. That's how Generics work, and there's a good reason for it. Java cannot allow you to add OrdinaryUser to a List<Admin>, and under your assumption that could happen:

List<User> users = new ArrayList<Admin>(); users.add(new OrdinaryUser()); // shouldn't be allowed!

The official term is that generic types are invariant with respect to their type parameter. It is best to google around for this term as it is already very well covered.

更多推荐

本文发布于:2023-08-07 12:47:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1464139.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:通配符   实例   列表   Java   Generics

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!