Question about generated equals() method
The generated equals() method does something that I find very surprising. It accesses the passed Objects private methods!
e.g.
public boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof Venue)) return false;
final Venue venue = (Venue) o;
if (!city.equals(venue.city)) return false;
if (!name.equals(venue.name)) return false;
if (!state.equals(venue.state)) return false;
return true;
}
I've been coding Java for years and always thought that private members cannot be accessed from anywhere except from within the same Object's code (i.e. they are encapsulated)
But this tells me that other Objects of the same class can also access these private fields.
Am I the only one surprised by this? Can someone point to some documentation explaining this?
And also, is this considered good style in general? I can see that in an automatically generated equals you would need to use private fields but otherwise this seems like dangerous style.
Please sign in to leave a comment.
>The generated equals() method does something that I find very surprising. It accesses the passed Objects private methods!
This is no problem, if the passed object is casted to the current
class.
Tom
Private members cannot be accessed from anywhere except from within the same class. But an instance of a class can access private members of another instance of the same class.
You may find some documentation here: http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#104285 (The Java Language Specification - Second Edition, 6.6 Access Control).
If you read any of the java programmer certification books it will explain this also. I suggest reading one of these books even if you don't care about the certification. The heller book does a good job.
Interesting. This sounds dangerous to me; I have never once felt a need to use this kind of access. Still, I guess its handy to know.
Can anyone give me some examples of situations where this access would be useful? I can see the equals method is one.... any others?
I do that quite often in factory methods. The default (and only, most of
the time) constructor is made private, there are no setters provided for
some private fields that can not be changed from outside and they are set
from the factory method.
Something like this:
public class TestClass {
private String type;
private String prop1;
private String prop2;
private TestClass(){};
public static TestClass createType1(String prop1, String prop2){
TestClass t = new TestClass();
t.type = "type1";
t.prop1 = prop1;
t.prop2 = prop2;
return t;
}
}
Note that some people prefer to always access the fields through
getters/setters (or some type of frameworks might require them, as
hibernate does, for instance) and provide private setters for the above
fields.
The same holds true for the case with the private setters, you access them
from an instance of the same class, not the same object.
HTH,
Andrei