18

So I was making a class the other day and used Eclipse's method to create the equals method when I realized that it generated the following working code:

class Test {
  private int privateInt;
  [...]
  public boolean equals(Object obj) {
    [...]
    Test t = (Test) obj;
    if ( t.privateInt == privateInt ) {
    [...]
  }
}

t.privateInt..???? It's suppose to be private! So I guess there is one more field visibility other than private, protected, package protected and public.

So what is happening here? How is this called? Where would somebody use this? Doesn't this break encapsulation? What if the class didn't have a mutator and I changed this? Does this happen to C++ as well? Is this an OO idiom? If not, then why did Java do it?

Generally, where can I find information about this?

Thank you.

pek
  • 17,847
  • 28
  • 86
  • 99

6 Answers6

25

It's accessible from different instances of the same class.

According to this page (bolding mine):

At the member level, you can also use the public modifier or no modifier (package-private) just as with top-level classes, and with the same meaning. For members, there are two additional access modifiers: private and protected. The private modifier specifies that the member can only be accessed in its own class.

For clarity I'll rewrite this line:

if ( t.privateInt == this.privateInt )

We can agree that "this.privateInt" should be allowed: you are accessing it from within the instance of class Test that the message "equals" has been sent to.

It's less clear that "t.privateInt" should be visible, because t is a separate instance of class Test and we are not executing inside its equals method. However java allows this since both objects (t and this) are of the same class Test and can see each others private members.

Michael Sharek
  • 5,043
  • 2
  • 30
  • 33
  • OK... I understand now... But WHY? Why did Java let this happen? Can you think of some real life examples. I get why it should work in equals.. But there must be a better example.. – pek Nov 26 '08 at 15:20
  • The only other examples would be similar to equals where you are given another instance of your class as an argument. As for why Java did it, it's pretty standard in OO languages - C++ works the same way. Overloading == in C++ : http://artis.imag.fr/~Xavier.Decoret/resources/C++/operator==.html – Michael Sharek Nov 26 '08 at 16:37
  • Soooo... its pretty useless trivia? – pek Nov 26 '08 at 16:45
  • 2
    As another bit of useless trivia, `private` has worked this way since it first appeared in Simula-67 (it was called `hidden` there, but it was also one of the 3 classic private/protected/public levels, and it worked exactly as it does in C++, Java, C# et al). – Pavel Minaev Jul 31 '09 at 06:02
4

Mike's quite correct; you are confusing objects (instances of a class) with the class itself. The members are private to the class, not any particular instance of the class.

I recall being just as surprised about this when I was new to Java.

Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
3

You are referencing it from within the same class. Thus, you know what you are doing and does not need to be protected from yourself.

mthurlin
  • 26,247
  • 4
  • 39
  • 46
3

One big reason that access to the private members of other instances is allowed is to permit "copy" functions -- they would be pretty much impossible otherwise. Also, if you didn't allow access by other instances, what would you allow for static methods?

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
1

The private variables of another instance of the same class can be accessed. This is because you are dealing with the implementation of the class, directly, which requires you to know about its internal, 'private' variables anyway.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
0

The simple answer to this confusion is to remember that private field are visible only and only in the class where they are initialize( and defined)....So when you make an object of the class inside the class, you can always access the private field of that class through the object reference. May be you feel its difficult but just think private field is just like a public field when you are using it inside the class where it is defined.