Java泛型:列表、列表<对象>、列表<?> [英] Java Generics: List, List&lt;Object&gt;, List&lt;?&gt;

查看:27
本文介绍了Java泛型:列表、列表<对象>、列表<?>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以尽可能详细地解释以下类型之间的区别吗?

Can someone explained, as detailed as possible, the differences between the following types?

List
List<Object>
List<?>

让我说得更具体一点.我什么时候想用

Let me make this more specific. When would I want to use

// 1 
public void CanYouGiveMeAnAnswer(List l) { }

// 2
public void CanYouGiveMeAnAnswer(List<Object> l) { }

// 3
public void CanYouGiveMeAnAnswer(List<?> l) { }

推荐答案

正如其他帖子所指出的,您是在询问称为泛型的 Java 功能.在 C++ 中,这称为模板.Java 中的此功能通常比 C++ 中的功能更易于使用.

As the other posts have noted, you are asking about a Java feature called generics. In C++, this is called templates. This feature in Java is usually easier to work with than the that found in C++.

让我从功能上回答你的问题(如果这对 OO 讨论来说不是一个顽皮的话).

Let me answer your questions functionally (if that's not a naughty word for OO discussions).

在泛型之前,有像 Vector 这样的具体类.

Before generics, there were concrete classes like Vector.

Vector V = new Vector();

向量包含您提供给它们的任何对象.

Vectors hold any object you give them.

V.add("This is an element");
V.add(new Integer(2));
v.add(new Hashtable());

他们通过将赋予它的所有值转换为一个对象(所有 Java 类的根)来实现这一点.当您尝试检索存储在 Vector 中的值时,您需要将该值转换回原始类(如果您想对其进行任何有意义的操作).

They do this by casting all values given to it into an Object (the root of all Java classes). When you attempt to retrieve the values stored in your Vector, you need to cast the value back into the original class (if you want to do anything meaningful with it).

String s = (String) v.get(0);
Integer i = (Integer) v.get(1);
Hashtable h = (Hashtable) v.get(2);

选角很快就会变老.不仅如此,编译器还会向您抱怨未经检查的强制转换.像这样转换的最紧迫的问题是 Vector 的使用者必须在编译时知道其值的类,以便正确转换.在 Vector 的生产者和消费者完全相互隔离的情况下(想想 RPC 消息),这可能是一个致命的问题.

Casting gets old fast. More than that, the compiler complains to you about unchecked casts. The most urgent problem with casting like this is that consumers of your Vector have to know the classes of its values at compile time in order to cast correctly. In cases where the producer of the Vector and the consumer of the same are completely isolated from each other (think RPC messages), this can be a fatal issue.

输入泛型.泛型尝试创建强类型类来执行泛型操作.

Enter generics. Generics attempt to create strongly typed classes to do generic operations.

ArrayList<String> aList = new ArrayList<String>();
aList.add("One");
String element = aList.get(0); // no cast needed
System.out.println("Got one: " + element); 

设计模式这本书鼓励读者从契约的角度思考,而不是具体的类型.将变量与其实现类分离是明智的(和代码重用).

The Design Patterns book encourages the reader to think in terms of contracts, not concrete types. There is wisdom (and code re-use) in divorcing variables from their implementing class.

考虑到这一点,您可能认为所有实现 List 对象都应该做相同的事情:add()get()size() 等等.稍微反思一下,你可以想象出许多以各种方式遵守 List 契约的 List 操作的实现(例如 ArrayList).但是,这些对象处理的数据类型与对它们执行的操作是正交的.

With this in mind, you might think that all implementations List objects should do the same set of things: add(), get(), size(), etc. With a little reflection, you can imagine many implementations of List operations that obey the List contract in various ways (e.g. ArrayList). However, the type of data these objects deal with is orthogonal to the actions performed on them.

把它们放在一起,你会经常看到以下类型的代码:

Put it all together and you'll see the following kinds of code frequently:

List<String> L = new ArrayList<String>();

您应该将其理解为L 是一种处理字符串对象的列表".当您开始处理工厂类时,处理契约而不是具体的实现是至关重要的.工厂在运行时生产各种类型的对象.

You should read that as "L is a kind of List that deals with String objects". When you start dealing with Factory classes, it is critical to deal with contracts rather than specific implementations. Factories produce objects of various types at runtime.

使用泛型非常简单(大多数情况下).

Using generics is pretty easy (most of the time).

有一天,您可能决定要实现自己的泛型类.也许您想编写一个新的数据库抽象接口来消除各种数据存储之间的差异.当您定义该通用类时,您将使用 作为将由方法操作的对象类型的占位符.

One day you may decide you want to implement your own generic class. Perhaps you want to write a new database abstraction interface that elides the differencesbetween various data stores. When you define that generic class, you will use <t> as a placeholder for the kind of object that will be manipulated by the methods.

如果您仍然感到困惑,请使用 List 的泛型类,直到您感到满意为止.稍后,您可以更加自信地深入研究实现.或者,您可以查看 JRE 附带的各种 List 类的源代码.开源在这方面很棒.

If you are still confused, use the generic classes for List until you are comfortable. Later, you can dive into the implementation with a bit more confidence. Or you can look at the source code for the various List classes that ship with the JRE. Open source is great that way.

查看 Oracle/Sun 关于泛型的文档.干杯.

Have a look at the Oracle/Sun docs about generics. Cheers.

这篇关于Java泛型:列表、列表<对象>、列表<?>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆