views:

233

answers:

1

I'm learning Java, and the book I'm reading has the following example on cloning. In clone(), my first instance is able to set buffer on the new object even though buffer is private. It seems like it should require the field to be protected for this to work.

Why is this allowed? Does clone() have special privileges that allows it to access the private fields?

public class IntegerStack implements Cloneable {
    private int[] buffer;
    private int top;

    // ... code omitted ...

    @Override
    public IntegerStack clone() {
        try{
            IntegerStack nObj = (IntegerStack) super.clone();
            nObj.buffer = buffer.clone();
            return nObj;
        } catch (CloneNotSupportedException e)
        {
            throw new InternalError(e.toString());
        }
    }
}
+10  A: 

The private modifier does not mean that only the same instance can access the field; it means only objects of the same class can access it.

The Java Language Specification says in §6.6, Access Control:

... 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.

In other words, anything inside the class can access it at any time. Even nested classes can access private members and constructors in the enclosing class, and vice versa.

(You're not alone in misunderstanding it; check out this much-upvoted answer to "What is your longest-held programming assumption that turned out to be incorrect?)

Michael Myers
thanks! I also know PHP, so I've verified that PHP's version of private actually works the same way.
Asa Ayers
I think most object-oriented languages work this way. I know C# and C++ do. Apparently Ruby and VB6 have instance-private variables, and Scale can do `private[this]`, but that's all I know of that work the other way. (I only know about Ruby, VB6, and Scala from the comments in the linked answer.)
Michael Myers