tags:

views:

259

answers:

8
private ArrayList<String> colors = new ArrayList<String>();

Looking at the example above, it seems the main point of generics is to enforce type on a collection. So, instead of having an array of "Objects", which need to be cast to a String at the programmer's discretion, I enforce the type "String" on the collection in the ArrayList. This is new to me but I just want to check that I'm understanding it correctly. Is this interpretation correct?

+2  A: 

Yes, your understanding is correct. The collection is strongly-typed to whatever type is specified, which has various advantages - including no more run-time casting.

GalacticCowboy
Doesn't the run-time casting still happen (concealed from the programmer)?
jpalecek
jpalecek: No, to quote rascher - "Even better - this check is done at compile time"
Björn
There is still run-time casting, but as a user of generic classes, you don't have to do it yourself usually.
Torsten Marek
+1  A: 

Yes. To maintain type safety and remove runtime casts is the correct answer.

Björn
A: 

Yeah, that's basically it. Before generics, one had to create an ArrayList of Objects. This meant that one could add any type of Object to the list - even if you only meant for the ArrayList to contain Strings.

All generics do is add type safety. That is, now the JVM will make sure that any object in the list is a String, and prevent you from adding a non-String object to the list. Even better: this check is done at compile time.

rascher
Note that they do not actually add type safety at runtime, only at compile time. The types are discarded at runtime and anything can happen. Generics are merely for documentation/clarity and compile-time checking.
davetron5000
@davetron5000 true! Java calls this "feature" Type Erasure: http://java.sun.com/docs/books/tutorial/java/generics/erasure.htmlPersonally, I find it to be the most annoying thing ever.
rascher
It was not possible to add reified generics without breaking compatibility with existing code. Neal Gafter explains this pretty thoroughly here: http://gafter.blogspot.com/2006/11/reified-generics-for-java.html
Mark Renouf
Right. Microsoft goes the easy route by breaking compatibility with each Major release of their .NET platform. In Java a Java 6 JVM is pretty much capable of running Java 1.2 code.
Joachim Sauer
Well, Microsoft "broke" compatibility by adding new classes (and in a new namespace to boot). At least in this case, that's not breaking compatibility...
Chris R. Donnelly
A: 

You may want to check out the tutorial in the Java site. It gives a good explanation of in the introduction.

Without Generics:

List myIntList = new LinkedList(); // 1
myIntList.add(new Integer(0)); // 2
Integer x = (Integer) myIntList.iterator().next();  // 3

With Generics

List<Integer> myIntList = new LinkedList<Integer>(); // 1'
myIntList.add(new Integer(0)); // 2'
Integer x = myIntList.iterator().next(); // 3'

I think it as type safety and also saving the casting. Read more about autoboxing.

KahWee Teng
With autoboxing, you can replacemyIntList.add(new Integer(0));with just myIntList.add(0);and this wouldn't be true with an untyped list.
Carl Manaster
A: 

You can add runtime checks with the Collections utility class.

http://java.sun.com/javase/6/docs/api/java/util/Collections.html#checkedCollection(java.util.Collection,%20java.lang.Class)

Also see checkedSet, checkedList, checkedSortedSet, checkedMap, checkedSortedMap

Peter Lawrey
+7  A: 

That's by far not the only use of generics, but it's definitely the most visible one.

Generics can be (and are) used in many different places to ensure static type safety, not just with collections.

I'd just like to mention that, because you'll come accross places where generics could be useful, but if you're stuck with the generics/collections association, then you might overlook that fact.

Joachim Sauer
I want to second this answer. Most developers will face java generics in the collection classes first. This is where generics sure make a big improvement to the compile time type checking. But there are a lot of patterns that emerge once you think in generics. E.g. factory methods like public <T> T createInstance(Class<? extends T> klass) and similiar. Generally most time you do a cast now, with generics you can replace this cast with a type safe expression.
ordnungswidrig
A: 

Yes, you are correct. Generics adds compile-time type safety to your program, which means the compiler can detect if you are putting the wrong type of objects into i.e. your ArrayList.

One thing I would like to point out is that although it removes the visible run-time casting and un-clutters the source code, the JVM still does the casting in the background.

The way Generics is implemented in Java it just hides the casting and still produces non-generic bytecode. An ArrayList<String> still is an ArrayList of Objects in the byte-code. The good thing about this is that it keeps the bytecode compatible with earlier versions. The bad thing is that this misses a huge optimization opportunity.

Zendar
A: 

You can use generic anywhere where you need a type parameter, i.e. a type that should be the same across some code, but is left more or less unspecified.

For example, one of my toy projects is to write algorithms for computer algebra in a generic way in Java. This is interesting for the sake of the mathematical algorithms, but also to put Java generics through a stress test.

In this project I've got various interfaces for algebraic structures such as rings and fields and their respective elements, and concrete classes, e.g. for integers or for polynomials over a ring, where the ring is a type parameter. It works, but it becomes somewhat tedious in places. The record so far is a type in front of a variable that spans two complete lines of 80 characters, in an algorithm for testing irreducibility of polynomials. The main culprit is that you can't give a complicated type its own name.

starblue