Previous | Next | Trail Map | Writing Java Programs | Objects, Classes, and Interfaces


Controlling Access to Member Variables

When you declare a member variable in a Java class, you can allow or disallow other classes and object to access that member variable. You do this through the use of access specifiers.

The Java language supports five distinct access levels for variables: private, private protected, protected, public, and, if left unspecified, "friendly". The following chart shows the access level permitted by each specifier.

                                sub-    pack-
Specifier               class   class   age     world
-----------------------------------------------------
private                 X
private protected       X       X
protected               X       X*      X
public                  X       X       X       X

friendly                X               X
The first column indicates whether the class itself has access to the variable defined by the access specifier. The second column indicates whether subclasses of the class (regardless of which package they are in) have access to the variable. The third column indicates whether classes in the same package (regardless of their parentage) as the class have access to the variable. And finally, the fourth column indicates that all classes have access to the variable.

You'll note that the protected/subclass intersection has an '*' -- this indicates that this particular access case has a special caveat which is discussed in detail below.

Let's look at each access level in more detail.

Private

Let's begin with the most restrictive access level--private. A private variable is only accessible to the class in which it is defined. To declare a private variable, use the keyword private. For example, the following class defines one private variable within it:
class Alpha {
    private int iamprivate;
}
Objects of type Alpha can inspect or modify the iamprivate variable, but objects of other types cannot. For example, the following class, regardless of which package it is in or its parentage, cannot access the iamprivate variable within the Alpha class.
class Beta {
    void accessMethod() {
        Alpha a = new Alpha();
        a.iamprivate = 10;      // illegal
    }
}
You can tell when one of your classes is attempting to access a variable to which it does not have access--the compiler will print an error message similar to the following and refuse to compile your program.
Beta.java:9: Variable iamprivate in class Alpha not accessible from class Beta.
        a.iamprivate = 10;     // illegal
         ^
1 error
Often new Java programmers wonder if one Alpha object can access the private variables of another Alpha object. This can be illustrated by the following example. Suppose the Alpha class contained an instance method that compared the current Alpha object (this) to another object based on their iamprivate variables:
class Alpha {
    private int iamprivate;
    boolean isEqualTo(Alpha anotherAlpha) {
        if (this.iamprivate == anotherAlpha.iamprivate)
            return true;
        else
            return false;
    }
}
This is perfectly legal. Objects of the same type have access to one another's private variables. This is because access restrictions apply at the class or type level (all instances of a class) rather than at the object level (this particular instance of a class).

Note: this is a Java language keyword that refers to the current object. For more information about how to use this see The Method Body.

Private Protected

The next most restrictive access specifier is private protected. This access level includes the private access level plus allows any of the class's subclasses to access the variable. To declare a private protected variable, use the keywords private protected. For example, the following class defines one private protected variable within it:
class Alpha {
    private protected int iamprivateprotected;
}
Objects of type Alpha can inspect or modify the iamprivateprotected variable. In addition, subclasses of Alpha also have access to iamprivateprotected. For instance, this subclass of Alpha can assign its iamprivateprotected variable to that of an Alpha object.
class Beta extends Alpha {
    void modifyVariable(Alpha a) {
        a.iamprivateprotected = this.iamprivateprotected;       // legal
    }
}

Protected

The next access level specifier is protected which allows the class itself, subclasses (with a caveat), and all classes in the same package to access the variable. To declare a protected variable, use the keyword protected. First let's look at how the protected specifier affects access for classes in the same package.

For example, take this version of the Alpha class which is now declared to be within a package named "Greek" and which has a single protected variable declared within it.

package Greek;

class Alpha {
    protected int iamprotected;
}
Now, suppose that the class, Gamma, was also declared to be a member of the Greek package (and is not a subclass of Alpha). The Gamma class can legally access the iamprotected variable declared within the Alpha class.
package Greek;

class Gamma {
    void accessMethod() {
        Alpha a = new Alpha();
        a.iamprotected = 10;    // legal
    }
}
That's pretty straightforward. Now, let's investigate how the protected specifier affects access for subclasses of Alpha.

Let's introduce a new class, Delta, that derives from Alpha but lives in a different package. The Delta class can access the iamprotected variable, but only on objects of type Delta or its subclasses. The Delta class cannot access the iamprotected variable on objects of type Alpha. For example, the accessMethod() in the following example attempts to access the iamprotected variable on an object of type Alpha, which is illegal, and on an object of type Delta, which is legal.

class Delta extends Alpha {
    void accessMethod(Alpha a, Delta d) {
        a.iamprotected = 10;    // illegal
        d.iamprotected = 10;    // legal
    }
}
If a class is both a subclass of and in the same package as the class with the protected variable, then the class has access to the protected variable.

Public

Now for the easiest access specifier--public. Any class, in any package, has access to a class's public variables. To declare a public variable, use the keyword public. For example,
package Greek;

class Alpha {
    public int iampublic;
}
Now, let's go back to our Beta class which is now in a different package than Alpha and is completely unrelated to Alpha (not a subclass of).
package Roman;

class Beta {
    void accessMethod() {
        Alpha a = new Alpha();
        a.iampublic = 10;       // legal
    }
}
As you can see from the above code snippet, Beta can legally inspect and modify the iampublic variable in the Alpha class.

Friendly

And finally, the last access level is what you get if you don't explicitly set a variable's access to one of the other levels. For example, this version of the Alpha class declares a single "friendly" variable and lives within the Greek package.
package Greek;

class Alpha {
    int iamfriendly;
}
The Alpha class has access to iamfriendly. In addition, all the classes declared within the same package as Alpha also have access to iamfriendly. For example, suppose that both Alpha and Beta were declared as part of the Greek package, then this Beta class
package Greek;

class Beta {
    void accessMethod() {
        Alpha a = new Alpha();
        a.iamfriendly = 10;     // legal
    }
}
can legally access iamfriendly as shown.


Previous | Next | Trail Map | Writing Java Programs | Objects, Classes, and Interfaces