Java: Why can I access private fields of other objects?

As you may have discovered, this compiles:

class MyClass {
    private int i = 7;
    public void m(MyClass notThis) {
        System.err.println(notThis.i);
    }
}

The reason is that access modifiers work on class level and not on object level. Two different objects of the same class can access each others private members.

That’s strange, why doesn’t it work on object level?

This is a good question. Smalltalk, for instance, does in fact enforce access control on object level.

Here are three reasons:

Reason 1: Enforcing it on class level allows the compiler to catch all violations in compiletime. Had it been on object level on the other hand, the compiler would have had to do one of the following things:

  • Guard every field access with something like if (obj != this) throw IllegalAccessException(); which would slow down execution, or
  • defensively reject anything but this.i (like obj.i) since it’s in general impossible to tell if obj == this in all executions. This would have been annoying in cases it was clear to the programmer that obj did in fact equal this.

Reason 2: The field you’re accessing (even if it’s of a different object in runtime) is declared in the file you’re editing. If you mess something up by modifying another objects state, the fault is in the file you have in front of you. There’s no spooky action at a distance.

Reason 3: Some methods such as equals, clone and copy constructors would be tricky to write without giving up encapsulation.

Comments