Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

remove(Object Element) of Collections - Reason for parameter type "Object" instead of "E"

 
Kalpana Periasamy
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Java Geeks,
This is my first post in Java Ranch. Happy new year to all.

Coming to the question, I was looking at the "Collections" interface. I saw these 2 methods.

void add(E element);
void remove(Object Element);

Why isnt the remove method declared as void remove(E Element)?

Thanks in advance,
Kalps.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Pie
Posts: 15437
41
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because the remove(Object element); method already existed before generics were added to Java (in Java 5). For backward compatibility reasons, the old method that takes an Object has been preserved. If Java would have had generics from the beginning, it wouldn't have had this method that takes an Object instead of an E.
 
Winston Gutkowski
Bartender
Pie
Posts: 10498
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesper de Jong wrote:Because the remove(Object element); method already existed before generics were added to Java (in Java 5)...

@Kalpana: And just to add to what Jesper said, there are other examples too, such as Map.get().
In practise, these methods don't violate type safety too much, since what they do relies on finding the passed object in the collection (which won't be the case if it's the wrong type). They are also documented to optionally throw ClassCastException if the passed type is incompatible.

Perhaps they'll add a delete(E element) method at some point, but I don't see any burning need for it.

Winston
 
Rob Spoor
Sheriff
Pie
Posts: 20606
60
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
They can't add new methods to any existing interfaces, or it would break all implementations by other developers. This actually is already the case with JDBC. PreparedStatement, ResultSet and a few other interfaces have received extra methods in Java 6 that will not be implemented by older drivers. Perhaps the JDBC framework has solved this by catching errors and transforming them in SQLExceptions (e.g. SQLFeatureNotSupportedException), but it's also possible that you get a NoSuchMethodError instead (I haven't tested this yet). Perfect.

However, as Winston said, there is no need for a method like that. remove accepts any object as its argument which mean that a delete(E) method would do exactly the same but with some extra compiler checking. During runtime the two would be equivalent since type erasure would turn delete(E) into delete(Object).
 
Stephan van Hulst
Bartender
Pie
Posts: 6098
71
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, there's another important reason.

The method takes an Object for greater flexibility. Say we have a variable:

List<? extends Number> numbers = new ArrayList<Integer>();

If the remove method took a generic type, we could not use it to remove anything from the numbers list. After all, numbers isn't aware of what the exact type argument is.
Since the remove takes an Object, we can try to remove anything from the list referenced by numbers. If the list doesn't contain the value, nothing happens.

Adding the wrong type to a list would cause great problems at runtime. That's why a compiler check is important. Removing a wrong type from a list does nothing, so checking is unnecessary.
 
Kalpana Periasamy
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@All : Thanks for the explanation.
For my understanding, what was the method definition of add before Generics were added in Java 5. Was it void add(Object element)? If so, when add(Object element) is rewritten as add(E element), why not remove(Object element) is rewritten?
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, Stephan's given one reason why they didn't.
 
Kalpana Periasamy
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand his reason. I think that I dint understand the basics of generics yet. Do you have any pointers to good generics tutorial?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic