Java泛型:List,List< Object&gt ;, List<> [英] Java Generics: List, List<Object>, List<?>

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

问题描述

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

 列表
列表<对象>
列表<?>

让我更具体一些。我何时想要使用

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

// 2
公共无效CanYouGiveMeAnAnswer(列表与LT;对象> L){}

// 3
公共无效CanYouGiveMeAnAnswer(列表与LT;→1){ }


解决方案

询问一个叫做泛型的Java特性。在C ++中,这被称为模板。



让我在功能上回答您的问题(如果这不是OO讨论的调皮话)。



在泛型之前,您有像Vector这样的旧的具体类。

  Vector V = new Vector(); 

向量包含您给它们的任何旧对象。

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

然而,他们通过将您给它的所有内容转换为Object(所有Java类的根)。没关系,直到您尝试检索存储在Vector中的值。当你这样做的时候,你需要将这个值转换回原来的类(如果你想对它做任何有意义的事情)。

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

施法变得非常快速。更重要的是,编译器会叮嘱你关于未经检查的强制转换。有关这方面的一个生动的例子,使用Apache的XML-RPC库(反正版本2)。最重要的问题是,Vector的消费者必须在编译时间中知道其值的确切类别才能正确转换。如果Vector和消费者的生产者彼此完全隔离,这可能是一个致命的问题。



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

  ArrayList< String> aList = new ArrayList< String>(); 
aList.add(One);
String element = aList.get(0); //不需要转换
System.out.println(Got one:+ element);

现在,如果您看一看四个 Design Patterns 书,你会注意到,从实施阶级中分离变量是有一定的智慧的。考虑合同而不是实施更好。所以,你可能会说所有的List对象都做同样的事情: add() get() size()等等。但是,List操作有许多实现可以选择以各种方式服从合约(例如 ArrayList )。但是,这些对象所处理的数据类型作为运行时考虑事项留给您,泛型类的用户。把它放在一起,你会经常看到下面这行代码:

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

您应该将其读为L是一种处理String对象的List。当你开始处理Factory类时,处理合同而不是特定的实现是至关重要的。工厂在运行时产生各种类型的对象。

使用泛型非常简单(大部分时间)。然而,你可能决定要实现一个通用类的一个糟糕的一天。也许你已经想到了一个伟大的新List实现。当您定义该类时,您可以使用< t> 作为将由方法操纵的对象类型的占位符。如果您感到困惑,请使用列表的通用类,直到您感觉舒适。然后,您可以更加自信地深入实施。或者您可以查看JRE附带的各种List类的源代码。开源很棒。



查看Oracle / Sun 有关泛型的文档
干杯。


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) { }

解决方案

As the other posts have noted, you're asking about a Java feature called generics. In C++, this is called templates. The Java beasties are far tamer to deal with.

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

Before generics, you had good old concrete classes like Vector.

Vector V = new Vector();

Vectors hold any old object you give them.

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

However, they do this by casting everything you give it into an Object (the root of all Java classes). That's OK until you attempt to retrieve the values stored in your Vector. When you do, 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);

Casting gets pretty old fast. More than that, the compiler whines at you about unchecked casts. For a vivid example of this, use the XML-RPC library from Apache (version 2 anyway). The most important problem with this is that consumers of your Vector have to know the exact class of its values at compile time in order to cast correctly. In cases where the producer of the Vector and the consumer are completely isolated from each other, 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); 

Now, if you take a look at the infamous gang of four's Design Patterns book, you'll notice that there is some wisdom in divorcing variables from their implementing class. It's better to think of contracts rather than implementation. So, you might say that all List objects do the same things: add(), get(), size(), etc. However, there are many implementations of List operations that may choose to obey the contract in various ways (e.g. ArrayList). However, the type of data these object deal with is left as a runtime consideration to you, the user of the generic class. Put it all together and you'll see the following line of code very frequently:

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

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). However, one awful day you may decide you want to implement a generic class. Perhaps you've thought of a great new List implementation. When you define that class, you use <t> as a placeholder for the kind of object that will be manipulated by the methods. If you're confused, use the generic classes for List until you're comfortable. Then, 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.

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

这篇关于Java泛型:List,List&lt; Object&gt ;, List&lt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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