Is it to maintain backwards compatibility with older (un-genericized) versions of Collection
? Or is there a more subtle detail that I am missing? I see this pattern repeated in remove
also (remove(Object o)
), but add
is genericized as add(E e)
.
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
contains()
takes anObject
because the object it matches does not have to be the same type as the object that you pass in tocontains()
; it only requires that they be equal. From the specification ofcontains()
,contains(o)
returns true if there is an objecte
such that(o==null ? e==null : o.equals(e))
is true. Note that there is nothing requiringo
ande
to be the same type. This follows from the fact that theequals()
method takes in anObject
as parameter, not just the same type as the object.Although it may be commonly true that many classes have
equals()
defined so that its objects can only be equal to objects of its own class, that is certainly not always the case. For example, the specification forList.equals()
says that twoList
objects are equal if they are bothList
s and have the same contents, even if they are different implementations of List. So coming back to the example in this question, it is possible to have aCollection<ArrayList>
and for me to callcontains()
with aLinkedList
as argument, and it might return true if there is a list with the same contents. This would not be possible ifcontains()
were generic and restricted its argument type toE
.In fact, the fact that
contains()
takes any object as an argument allows an interesting use where you can to use it to test for the existence of an object in the collection that satisfies a certain property:Because otherwise it could have only be compared to the exact match of parameter type, specifically wildcarded collections would have stopped working, e.g.
EDIT
For doubters who think that's not one of the reasons, here is a modified array list with a would be generified contains method
Basically
contains( Object o )
is a hack to make this very common use case to work with Java Generics.It is because the
contains
function utilizes theequals
function, and theequals
function is defined in the base Object class with a signature ofequals(Object o)
rather thanequals(E e)
(since not all classes are generic). Same case with theremove
function - it traverses the collection using theequals
function which takes an Object argument.This doesn't directly explain the decision however, as they could've still used type E and allowed it to be automatically cast to type Object on the call to
equals
; but I imagine they wanted to allow the function to be called on other Object types. There's nothing wrong with having aCollection<Foo> c;
and then callingc.contains(somethingOfTypeBar)
- it will always return false, and so it eliminates the need for a cast to type Foo (which can throw an exception) or, to protect from the exception, atypeof
call. So you can imagine if you're iterating over something with mixed types and callingcontains
on each of the elements, you can simply use the contains function on all of them rather than needing guards.It's actually reminiscent of the "newer" loosely-typed languages, when you look at it that way...
"does that basket of apples contain this orange?"
clearly a TRUE answer cannot be given. but that still leaves too possibilities:
the collection api chose the 1st one. but the 2nd choice would also make perfect sense. a question like that is a bullshit question 99.99% of times, so don't even ask!
Answered here.
Why aren't Java Collections remove methods generic?
In short, they wanted to maximize backwards compatibility, because collections have been introduced long before generics.
And to add from me: the video he's referring is worth watching.
http://www.youtube.com/watch?v=wDN_EYUvUq0
update
To clarify, the man who said that (in the video) was one of the people who updated java maps and collections to use generics. If he doesn't know, then who.