Access private field of another object in same class

I am also a bit curious with the answer.

The most satisfying answer that I find is from Artemix in another post here (I'm renaming the AClass with Person class): Why have class-level access modifiers instead of object-level?

The private modifier enforces Encapsulation principle.

The idea is that 'outer world' should not make changes to Person internal processes because Person implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).

When instance of Person accesses internals of other Person instance - you can be sure that both instances always know the details of implementation of Person. If the logic of internal to Person processes is changed - all you have to do is change the code of Person.

EDIT: Please vote Artemix' answer. I'm just copy-pasting it.


Good question. It seems that object level access modifier would enforce the Encapsulation principle even further.

But actually it's the other way around. Let's take an example. Suppose you want to deep copy an object in a constructor, if you cannot access the private members of that object. Then the only possible way is to add some public accessors to all of the private members. This will make your objects naked to all other parts of the system.

So encapsulation doesn't mean being closed to all of the rest of the world. It means being selective about whom you want to be open to.


See the Java Language Specification, Section 6.6.1. Determining Accessibility

It states

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

Click the link above for more details. So the answer is: Because James Gosling and the other authors of Java decided it to be that way.


This works because you are in the class Person - a class is allowed to poke inside it's own type of class. This really helps when you want to write a copy constructor, for example:

class A
{
   private:
      int x;
      int y;
   public:
      A(int a, int b) x(a), y(b) {}
      A(A a) { x = a.x; y = y.x; }
};

Or if we want to write operator+ and operator- for our big number class.


Just my 2 cents on the question of why the semantics of the private visibility in Java is class level rather than object level.

I would say that convenience seems to be the key here. In fact, a private visibility at object level would have forced to expose methods to other classes (e.g. in the same package) in the scenario illustrated by the OP.

In truth I was not able neither to concoct nor to find an example showing that the visibility at class-private level (like offered by Java) creates any issues if compared to visibility at object-private level.

That said, programming languages with a more fine-grained system of visibility policies can afford both object visibility at object level and class level.

For example Eiffel, offers selective export: you can export any class feature to any class of your choice, from {NONE} (object-private) to {ANY} (the equivalent of public, and also the default), to {PERSON} (class-private, see the OP's example), to specific groups of classes {PERSON, BANK}.

It's also interesting to remark that in Eiffel you don't need to make an attribute private and write a getter to prevent other classes from assigning to it. Public attributes in Eiffel are by default accessible in read-only mode, so you don't need a getter just to return their value.

Of course you still need a setter to set an attribute, but you can hide it by defining it as "assigner" for that attribute. This allows you, if you wish, to use the more convenient assignment operator instead of the setter invocation.