Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics: List, List<Object>, List<?>

Tags:

java

generics

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) { } 
like image 317
ForYourOwnGood Avatar asked Jan 29 '09 00:01

ForYourOwnGood


People also ask

What is the difference between list <?> And list Object?

In practical terms there is no difference, they both compile down to the exact same code. List<Object> though is showing that you have thought about what will go in the list and know it could be anything, whereas List on its own shows nothing.

What is the meaning of list <?> In Java?

In Java, a list interface is an ordered collection of objects in which duplicate values can be stored. Since a List preserves the insertion order, it allows positional access and insertion of elements. List interface is implemented by the following classes: ArrayList. LinkedList.

What does <? Super E mean?

super E> , it means "something in the super direction" as opposed to something in the extends direction.


1 Answers

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++.

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

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()); 

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); 

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.

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>(); 

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.

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.

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

like image 198
jjohn Avatar answered Sep 22 '22 17:09

jjohn