23

An instance of a class, in Java, can access private fields of a different instance of its own type, such as in the following listing:

public class Foo {
  private int secret;
  public void bar(final Foo foo) {
    foo.secret = 100;
  }
}

What would be the argument for such semantics (when designing a language)?

Pétur Ingi Egilsson
  • 4,368
  • 5
  • 44
  • 72
  • Well, it's all one class, so you can access your own private members. If you don't want to update `secret` for example, just don't. Coding can't protect you from yourself. – markspace Jun 02 '15 at 19:03
  • 6
    The definition of `private` says only instances of `Foo` can access it. Since you are in `Foo` you can access it. – Elliott Frisch Jun 02 '15 at 19:03
  • 4
    The semantics of the language allow this, I am asking why. – Pétur Ingi Egilsson Jun 02 '15 at 19:04
  • Lets maybe ask different question: why shout it not be allowed for `Foo` class to have access to private fields of different `Foo` instances than referenced by `this`? – Pshemo Jun 02 '15 at 19:06
  • @Pshemo I would be interested in an answer to that as well. I asked for an argument hoping it would present both for and against. – Pétur Ingi Egilsson Jun 02 '15 at 19:10
  • What would be gained by preventing a class from accessing fields of another instance of the same class. Java doesn't ask "why now" It only tries to have features which have some value. – Peter Lawrey Jun 02 '15 at 19:23
  • 1
    Without this, how would you implement an `equals(Foo other)` method? – Thilo May 23 '20 at 10:21
  • @Thilo I like your question, it got me thinking. But I do feel it is only relevant for languages such as Java, where the language specification dictates that if two objects are equal in terms of equals(...) then they must have the same hashCode(). My question has to do with "when designing a language", as such the specification of some said designed language could be that two objects are equal in terms of equals(...) iff they have the same observable (public in terms of Java) state. – Pétur Ingi Egilsson Jul 06 '20 at 18:47

3 Answers3

18

First you have to ask "why have private fields at all?"

Private fields are primarily for encapsulation: a consumer of a class shouldn't have to know the internals of that class' implementation, and in fact those internals should be actively hidden from the consumer. Otherwise, if a user relied on those internals, then the implementer would be forced to support them or break backwards compatibility. In other words, it protects both the user and designer of the class:

  • users are protected from implementation changes breaking their code
  • the designer is protected from having to keep implementation details features unchanged forever

But a class doesn't need to be protected from itself; it doesn't need to worry about the case where one bit of its code changes, but another bit (that uses the first bit) can't change. Backwards compatibility is not a concern, because the class is developed and deployed as a single, atomic chunk of code. In other words, neither of the above protections are needed.

Since there's no need to protect the fields, and since it's often necessary to see them (for instance, to compare if two objects are equal), they're visible within the class.

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • Why can't a class' code change within versions? (I probably just didn't understand you.) I'd say: _"Changes inside the class, can easily be modified by the designer to support any changes. Public fields can not, since it can break code __outside__ the authers scope."_ – Mordechai Jun 02 '15 at 19:11
  • @MouseEvent because internals are subject to change. Imagine you were relying on internal fields of the `FileInputStream` class and all the sudden NIO comes out were `FileInputStream` is completely changed to take advantage of native io operations. Now all the sudden the field your code reads is no longer there as it is implemented in native code. – RecursiveExceptionException Aug 19 '16 at 22:19
6

The private field is meant to tell other programmers not to mess with it.

Presumably, everyone working in a single class knows what all the variables do. The private field doesn't hide your own code from you, just from outside.

Ryan Goldstein
  • 523
  • 3
  • 14
1

You can copy/compare values without additional getters and change field without setters. Don't know if in the JVM such simple methods invocations are optimized in any way, but if not, then it produces some overhead.

One may think that keeping such "open" access may lead to some security issues, but when implemeting a class you provide all methods for manipulation of these variables. No one can change them from classes extending this class. As a matter of fact, they are still private - accessible only from your code.

Keep also in mind that logically a class often is destined to do one job. It can be beneficial to share some information and ease access, especially in cases when large amounts of instances are produced. When dealing with cases when more control is needed one can always use package access modifier (which is more "private" in a sense...) or limit instance count with a singleton/factory pattern.

freakybit
  • 59
  • 5