What is Generics?
What is Generics? |
- J2SE 5.0 provides compile-time type safety with the Java Collections framework through generics
- Generics allows you to specify, at compile-time, the types of objects you want to store in a Collection. Then when you add and get items from the list, the list already knows what types of objects are supposed to be acted on.
- So you don’t need to cast anything. The “<>” characters are used to designate what type is to be stored. If the wrong type of data is provided, a compile-time exception is thrown.
The Legacy Way to Do Collections |
Here’s a review of a pre-Java 5 ArrayList intended to hold Strings.
List myList = new ArrayList(); // can't declare a type
myList.add("Hello"); // OK, it will hold Strings
myList.add(new Dog()); // and it will hold Dogs too
myList.add(new Integer(42)); // and Integers...
- A non-generic collection can hold any kind of object!
- A non-generic collection is quite happy to hold anything that is NOT a primitive.
- This meant it was entirely up to the programmer to be…careful.
- Having no way to guarantee collection type wasn’t very programmer-friendly for such a strongly typed language.
And since a collection could hold anything, the methods that get objects out of the collection could have only one kind of return type-java.lang.Object.
That meant that getting a String back out of our only-Strings-intended list required a cast:
String s = (String) myList.get(0);
And since you couldn’t guarantee that what was coming out really was a String (since you were allowed to put anything in the list), the cast could fail at runtime.
So, generics takes care of both ends (the putting in and getting out) by enforcing the type of your collections. Let’s update the String list:
List<String> myList = new ArrayList<String>();
myList.add("Fred"); // OK, it will hold Strings
myList.add(new Dog()); // compiler error!!
Using Generics |
So, now that what you put IN is guaranteed, you can also guarantee what comes OUT, and that means you can get rid of the cast when you get something from the collection.
Instead of
String s = (String)myList.get(0);
// pre-generics, when a String wasn't guaranteed
we can now just say
String s = myList.get(0);
The compiler already knows that myList contains only things that can be assigned to a String reference, so now there’s no need for a cast. So far, it seems pretty simple.
And with the new for loop, you can of course iterate over the guaranteed-to-be-String list:
for (String s : myList) {
int x = s.length();
// no need for a cast before calling a String method!
// The compiler already knew "s" was a String coming from MyList
Recent Comments