This Java program I got from a blog does not compile:
import java.util.*;
class Egg
{
}
class Muffin
{
}
public class Breakfast
{
private List<Egg> eggs;
private List<Muffin> muffins;
public void add(List<Egg> moreEggs) {
this.eggs.addAll(moreEggs);
}
public void add(List<Muffin> moreMuffins) {
this.muffins.addAll(moreMuffins);
}
}
The error message is:
name clash: add(java.util.List<Muffin>) and add(java.util.List<Egg>) have the same erasure
I was amazed when I saw that. I finally found an explanation in this forum.
What is happening is that (I quote) “Parameterized types (aka Generics) are only to restrict the use to enter the right object into the collection. All the generic information is erased by the compiler.”
So that why I got a name clash error. Both add(java.util.List<Muffin>) and add(java.util.List<Egg>) are in fact the same method add(java.util.List)!!!
Generics in Java are only used at compile time. They don’t even exist at run time!
PS:
I am a fan of Erasure, the group. Vince Clark was the initiator of Depeche Mode after all…
Madhav says
Nice! Never came across that one! Well its also quite understandable as generics are usually used to help the programmer’s not make errors by adding wrong objects to lists and thus is not needed at runtime.
Eddy Young says
The rude comment would be, people should pay more attention to the Java Specs before complaining. They should not start screaming just because they’ve been caught with their pants down after mis-understanding how an aspect of the language works.
Java Generics was always intended for type-safety at compile-time and not for type information to be retained at run-time. So, when a program executes, a List remains a list, however it is parameterised.
Type erasure exists because the JCP wanted to maintain backward compatibility. Allowing for List and List to be completely different types would have broken many programs. Your normal List (parameterised with Object) would no longer mean the same thing as List, and vice-versa. Even C# side-steps the problem by offering entirely different classes for generics collections. I am not aware if there are plans for this in Java in the future — too much C# coding lately and not enough time to keep up with what is happening on the Java front :-)
That said, knowing the specifications of Generics, programmers should be able to design their program around those.
Harish says
I have this site to be quite useful, although it does go into a lot of detail about Java generics:
http://angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Harish
Eddy Young says
All the < and > in my comment have been interpreted as HTML, so that part of it does not make any sense.
What I meant above is, had Java Generics been implemented for parameterised types to be completely different, backward compatibility would have been broken. In existing programs, a method expecting a “list of objects” as argument will no longer work with a “list of eggs”.
— Eddy
avinash says
Yes,
As Madhav and Eddy pointed out, this behavior is perfectly understandable but, still, I was amazed because of my dynamic language background.
It feels so, ahem, bizarre that List<Egg> is not a type…
Eddy Young says
Well, let’s take a packaging example. You can have an “egg packaging” or you could have a “package holding eggs”. In the first case, the packaging would be egg-shaped to hold just eggs, whereas in the second case you’re merely saying, “careful there are eggs in this box”.
Generics does the second. Strong-typing does the first.
selven says
hmmm that’s not a big deal. Seeing the title i thought java had some major disadvantage and ppl have started accepting to throw that away.
+$3|
avinash says
Yep.
Generics in Java is a compiler feature which prevents people from adding eggs in lists of muffins.
It also allows people to remove muffins from lists of muffins without going through the Object hassle (automatic boxing and unboxing).
This is good enough I guess… for a static programming language.
No need to throw Java away yet, Selven :-)
javed mandary says
Hi,
thats so really cool.
By the way before your addAll your eggs and muffins don’t forget to initialize those lists .. dont want to get a NullPointerException do you?
avinash says
Oops!
avinash says
Or, now that I think of it, this does not really matter Javed as the program does not even compile :-)
Eddy Young says
@javed: Noticed that, too, but discarded it as a typo (like the capitalisation — or lack of — of the type parameter.
nasrullah says
Being an Ubuntu user I am very happy to visit your nice blog.
Merc,i Avinash