-1

In Bloch's Effective Java, 2nd edition, Item 11: Override clone judiciously has the following example:

class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;
    public Stack() {
        this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }
    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }
    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference
        return result;
    }
    // Ensure space for at least one more element.
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }

    @Override public Stack clone() {
        try {
            Stack result = (Stack) super.clone();
            result.elements = elements.clone();
            return result;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

As you can see, in the clone() method, a new object of type Stack is created, called result. We subsequently clone result.elements, despite the fact that the Stack class defines elements as a private member. What's going on and why is it permitted?

Abhishek Divekar
  • 1,131
  • 2
  • 15
  • 31
  • @JEY Thank you. Mind providing some reasoning for why this is permitted? – Abhishek Divekar Jun 22 '17 at 11:29
  • did you read the documentation ? – JEY Jun 22 '17 at 11:30
  • @JEY yes I did. Did you read my question? It talks about accessing private members of different instances in the same class, which Java permits. I would like to know why. The example you pointed out deals with accessing private members in different classes, which is not permitted. – Abhishek Divekar Jun 22 '17 at 11:34
  • Maybe https://stackoverflow.com/questions/1548879/java-accessing-private-fields-directly-from-another-instance-of-the-same-class –  Jun 22 '17 at 11:34
  • because you call it in the `Stack` class, so what is the reason that we can't do it ? – Phạm Lam Jun 22 '17 at 11:48

2 Answers2

2

A private member is only visible from other members in the same class, not especially in the same instance.

EDIT :

down vote The private modifier enforces Encapsulation principle.

Here is a quote from a similar question about C# but the principle is the same.

The private modifier enforces Encapsulation principle.

The idea is that 'outer world' should not make changes to AClass internal processes because AClass 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 AClass accesses internals of other AClass instance - you can be sure that both instances always know the details of implementation of AClass. If the logic of internal to AClass processes is changed - all you have to do is change the code of AClass.

Furthermore is allows to override equals() or compareTo()without having to expose the attributes involved in their evaluation.

C.Champagne
  • 5,381
  • 2
  • 23
  • 35
  • Why was this permitted? I seems unintuitive. – Abhishek Divekar Jun 22 '17 at 11:31
  • @abhidivekar it's not, it's perfectly normal. – jwenting Jun 22 '17 at 11:33
  • @jwenting Perhaps I always had the impression that an object, once created, is impenetrable as far as its private members are concerned. I thought this should hold even when externally objects of the same class are passed as arguments. What is the advantage this design? – Abhishek Divekar Jun 22 '17 at 11:36
  • 2
    @abhidivekar performance is one reason, and an important one. Accessing the field directly rather than through an accessor is faster. While not usually very important, during bulk operations it can make the difference between an application that performs well and one that crawls to a halt. Another reason is accessing things that have no accessors, especially important for cloning of course. – jwenting Jun 22 '17 at 11:39
  • Thank you for clarifying – Abhishek Divekar Jun 22 '17 at 11:51
0

That's allowed as per the language specification. Private access means a field or method is visible to instances of the same CLASS, not exclusively to the instance.

This is no special permission for certain methods (like clone) but for any method within the same class.

jwenting
  • 5,505
  • 2
  • 25
  • 30