Reputation: 239
Vector v = new Vector();
String a = "element";
String b = "element";
v.add(a);
v.contains(b) // true
So my question: if the type of the elements in the vector
are Object
than how contains
compare the Object
inside with the String
outside if equals()
is not overriden as an Object
I would like to know what's going on under the surface.
Upvotes: 2
Views: 92
Reputation: 95508
See here:
Returns
true
if this vector contains the specified element. More formally, returnstrue
if and only if this vector contains at least one elemente
such that(o==null ? e==null : o.equals(e))
.
The .equals
that ends up being called is the overridden .equals
. The fact that the method parameter is typed with Object
doesn't mean that the vector will use .equals
method of the Object
class; it will use the overridden .equals
method if one exists (otherwise using the one inherited from Object
). The parameter being typed Object
just means that you can pass in anything that is an Object
(which String
is, since all Java classes inherit from Object
).
Your confusion stems from the fact that the method invoked at runtime depends on the actual type of the object whose method is being invoked. Look at the JLS section on runtime evalution of method invocations for more details. You can see that it mentions a "target reference", which is the object whose method you are invoking.
Consider what would happen otherwise: behavior would change based on the type of the method parameter, rather than the type of the instance. This would completely defeat polymorphism! Consider the oft-used Animal
example: let's say there is a single method called makeNoise()
that returns the string "Noise!"
. Now you have two subclasses Dog
and Cat
that have overridden the method to return "Woof!"
and "Meow!"
respectively. Let's now say you have this method:
public void animalNoiseMaker(Animal animal) {
System.out.println(animal.makeNoise());
}
Going by your expectation, regardless of whether you passed in a Dog
or Cat
instance, it would call makeNoise
on Animal
every time and print Noise!
because the parameter type is Animal
. This is not very useful behavior.
Upvotes: 3
Reputation: 11
Object already contains a definition for the equals method. Therefore, if the object you are calling contains on (b in this case) is of a class that does not override the equals method, it will use Object's definition of equals.
The definition of equals in Object compares the address of the two objects and returns true if they are equal. From https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object) :
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
If the class overrides the equals method (as is the case for String) then the overriding version will be used.
Upvotes: 1
Reputation: 24316
You are using what are typically called 'raw types' for your collection. You can add whatever you like to it, but at run time it may cause issues (type casting). See here for a discussion
Upvotes: 0
Reputation: 393781
Vector
's contains
method calls indexOf
, which compares the elements of the Vector
with the element we are searching for using equals
.
If equals
is executed on an instance whose runtime type is String
(which is the case in your code), String
's equals
is executed (that's method overriding), and if the passed parameter is also a String
and contains the same characters in the same order, it will return true.
Here's what's going "under the surface" :
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
public synchronized int indexOf(Object o, int index) {
if (o == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i])) // if the runtime type of o is String,
// String's equals is executed
return i;
}
return -1;
}
Upvotes: 1