The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Controlling Access to Members of a Class

An access level determines whether other classes can use a particular member variable or call a particular method. The Java programming language supports four access specifiers for member variables and methods: private, protected, public, and, if left unspecified, package private. The following table shows the access permitted by each specifier.
Access Levels
Specifier Class Package Subclass World
private Y N N N
no specifier Y Y N N
protected Y Y Y N
public Y Y Y Y
The first column indicates whether the class itself has access to the memeber defined by the access level. As you can see, a class always has access to its own members. The second column indicates whether classes in the same package as the class (regardless of their parentage) have access to the member. A package groups related classes and interfaces and provides access protection and namespace management. You'll learn more about packages in the section Creating and Using Packages (in the Learning the Java Language trail). The third column indicates whether subclasses of the class — regardless of which package they are in — have access to the member. The fourth column indicates whether all classes have access to the member.

Access levels affect you in two ways. First, when you use classes that come from another source, such as the classes in the Java platform, access levels determine which members of those classes your classes can use. Second, when you write a class, you need to decide what access level every member variable and every method in your class should have. One way of thinking about access levels is in terms of the API: access levels directly affect the public API of a class and determine which members of the class can be used by other classes. You need to put as much effort into deciding the access level for a member as you put into making other decisions about your class's API, such as naming methods.

Let's look at a collection of classes and see access levels in action. The following figure shows the four classes that comprise this example and how they are related.

Classes and Packages of the Example Used to Illustrate Access Levels

Class Access Level

Here's a listing of a class, Alpha, whose members other classes will be trying to access. Alpha contains one member variable and one method per access level. Alpha is in a package called One:
package One;
public class Alpha {
    //member variables
    private   int iamprivate = 1;
              int iampackage = 2;  //package access
    protected int iamprotected = 3;
    public    int iampublic = 4;

    //methods
    private void privateMethod() {
        System.out.println("iamprivate Method");
    }
    void packageMethod() { //package access
        System.out.println("iampackage Method");
    }
    protected void protectedMethod() {
        System.out.println("iamprotected Method");
    }
    public void publicMethod() {
        System.out.println("iampublic Method");
    }

    public static void main(String[] args) {
        Alpha a = new Alpha();
        a.privateMethod();   //legal
        a.packageMethod();   //legal
        a.protectedMethod(); //legal
        a.publicMethod();    //legal

        System.out.println("iamprivate: "
            + a.iamprivate);    //legal
        System.out.println("iampackage: "
            + a.iampackage);    //legal
        System.out.println("iamprotected: "
            + a.iamprotected"); //legal
        System.out.println("iampublic: "
            + a.iampublic);     //legal
    }
}
As you can see, Alpha can refer to all its member variables and all its methods, as shown by the Class column in the preceding table. The output from this program is:
iamprivate Method
iampackage Method
iamprotected Method
iampublic Method
iamprivate: 1
iampackage: 2
iamprotected: 3
iampublic: 4
A member's access level determines which classes have access to that member, not which instances have access. So, for example, instances of the same class have access to one another's private members. Thus, we can add to the Alpha class an instance method that compares the current Alpha object (this) to another object, based on their iamprivate variables:
package One;
public class Alpha {
    ...
    public boolean isEqualTo(Alpha anotherAlpha) {
        if (this.iamprivate == anotherAlpha.iamprivate) {
        //legal
            return true;
        } else {
            return false;
        }
    }
}

Package Access Level

Now consider the following class, DeltaOne, which is in the same package as Alpha. The methods and the variables this class can use are predicted by the Package column in the preceding table.
package One;
public class DeltaOne {
    public static void main(String[] args) }
        Alpha a = new Alpha();
        //a.privateMethod();  //illegal
        a.packageMethod();    //legal
        a.protectedMethod();  //legal
        a.publicMethod();     //legal
        //System.out.println("iamprivate: "
        //  + a.iamprivate);   //illegal
        System.out.println("iampackage: "
            + a.iampackage);   //legal
        System.out.println("iamprotected: "
            + a.iamprotected); //legal
        System.out.println("iampublic: "
            + a.iampublic);    //legal
    }
}
DeltaOne cannot refer to the iamprivate variable or invoke privateMethod but can access the other members of Alpha. If you remove the comment from the lines of code that are commented out and try to compile the class, the compiler will generate errors. Here's the output from the program when you run it as shown:
iampackage Method
iamprotected Method
iampublic Method
iampackage: 2
iamprotected: 3
iampublic: 4

Subclass Access Level

The next class, AlphaTwo, is a subclass of Alpha but is in a different package. You can predict what member variables and methods it can use by looking at the Subclass column in the previous table:
package two;
import One.*;
public class AlphaTwo extends Alpha {
    public static void main(String[] args) {
        Alpha a = new Alpha();
        //a.privateMethod();   //illegal
        //a.packageMethod();   //illegal
        //a.protectedMethod(); //illegal
        a.publicMethod()       //legal

        //System.out.println("iamprivate: "
        //   + a.iamprivate);    //illegal
        //System.out.println("iampackage: "
        //   + a.iampackage);    //illegal
        //System.out.println("iamprotected: "
        //   + a.iamprotected);  //illegal
        System.out.println("iampublic "
            + a.iampublic);      //legal

        AlphaTwo a2 = new AlphaTwo();
        a2.protectedMethod();   //legal
        System.out.println("iamprotected: "
            + a2.iamprotected); //legal
    }
}
Note that AlphaTwo> cannot call protectedMethod or access iamprotected,/code> on the Alpha instance (it's superclass) but can call protectedMethod and access iamprotected on an instance of AlphaTwo or an instance of a subclass of AlphaTwo. In other words, the protected access level allows a subclass to refer to a protected member only through an object reference that is the same type as the class or one of its subclasses. The output displayed when running AlphaTwo is:
iampublic Method
iampublic: 4
iamprotected Method
iamprotected: 3

World Access Level

Finally, DeltaTwo is not related through the class hierarchy to Alpha and is in a different package than Alpha. As the World column in the preceding table shows, DeltaTwo can access only the public members of Alpha:
package Two;
import One.*;
public class DeltaTwo {
    public static void main(String[] args) {
        Alpha alpha = new Alpha();
        //alpha.privateMethod();   //illegal
        //alpha.packageMethod();   //illegal
        //alpha.protectedMethod(); //illegal
        alpha.publicMethod();      //legal
        //System.out.println("iamprivate: "
        //   + a.iamprivate);      //illegal
        //System.out.println("iampackage: "
        //   + a.iampackage);      //illegal
        //System.out.println("iamprotected: "
        //   + a.iamprotected);    //illegal
        System.out.println("iampublic: "
            + a.iampublic);        //legal
    }
}
Here's the output from DeltaTwo:
iampublic Method
iampublic: 4

: If other programmers use your class, you want to ensure that errors from misuse cannot happen. Access levels can help you do this. The following tips can help you decide what access level is appropriate for a particular member.
  • Use the most restrictive access level that makes sense for a particular member. Use private unless you have a good reason not to.
  • Avoid public member variables except for constants. [PENDING: Insert footnote: Many of the examples in the tutorial use public member variables. Examples and non-production code don't have to live up to the rigid design standards that an API does.] Public member variables tend to link you to a particular implementation and can lead to bugs and misuse. Furthermore, if a member variables can be changed only by calling a method, you can notify other classes or objects of the change. Notification is impossible if you allow public access to a member variable. You might decide to grant public access if doing so gives you significant performance gains.
  • Limit the number of protected and package member variables.
  • If a member variable is a JavaBeansTM property, it must be privat3e.


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.