站内搜索: 请输入搜索关键词
当前页面: 在线文档首页 > Java Tutorial 5.0 英文版

Controlling Access to Members of a Class - Java Tutorial 5.0 英文版

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 member 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 Creating and Using Packages (in the Learning the Java Language trail) section. The third column indicates whether subclasses of the class — declared outside this package — 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

Classes and Packages of the Example Used to Illustrate Access Levels

Class Access Level

Here's a listing of a class, Alpha (in a .java source file), 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 privateVariable = 1;
              int packageVariable = 2;  //default access
    protected int protectedVariable = 3;
    public    int publicVariable = 4;

    //methods
    private void privateMethod() {
        System.out.format("privateMethod called%n");
    }
    void packageMethod() { //default access
        System.out.format("packageMethod called%n");
    }
    protected void protectedMethod() {
        System.out.format("protectedMethod called%n");
    }
    public void publicMethod() {
        System.out.format("publicMethod called%n");
    }

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

        System.out.format("privateVariable: %2d%n",
            a.privateVariable);    //legal
        System.out.format("packageVariable: %2d%n",
            a.packageVariable);    //legal
        System.out.format("protectedVariable: %2d%n",
            a.protectedVariable); //legal
        System.out.format("publicVariable: %2d%n",
            a.publicVariable);     //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:
privateMethod called
packageMethod called
protectedMethod called
publicMethod called
privateVariable: 1
packageVariable: 2
protectVariable: 3
publicVariable: 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 privateVariables:
package one;
public class Alpha {
    ...
    public boolean isEqualTo(Alpha anotherAlpha) {
        if (this.privateVariable == anotherAlpha.privateVariable) {
        //legal
            return true;
        } else {
            return false;
        }
    }
}

Package Access Level

Now consider the following class, DeltaOne (in a .java source file), 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.format("privateVariable:  %2d%n",
      //    a.privateVariable);    //illegal
        System.out.format("packageVariable:  %2d%n",
            a.packageVariable);    //legal
        System.out.format("protectedVariable: %2d%n",
            a.protectedVariable); //legal
        System.out.format("publicVariable: %2d%n",
            a.publicVariable);    //legal
    }
}
DeltaOne cannot refer to privateVariable 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:
packageMethod called
protectedMethod called
publicMethod called
packageVariable: 2
protectedVariable: 3
publicVariable: 4

Subclass Access Level

The next class, AlphaTwo (in a .java source file), 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.format("privateVariable:   %2d%n",
      //  a.privateVariable);     //illegal
      //System.out.format("packageVariable:   %2d%n",
      //  a.packageVariable);     //illegal
      //System.out.format("protectedVariable: %2d%n",
      //  a.protectedVariable);   //illegal
        System.out.format("publicVariable:    %2d%n",
          a.publicVariable);      //legal

        AlphaTwo a2 = new AlphaTwo();
        a2.protectedMethod();    //legal
        System.out.format("protectedVariable: %2d%n",
          a2.protectedVariable); //legal
    }
}

World Access Level

Finally, DeltaTwo (in a .java source file) 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 a = new Alpha();
      //a.privateMethod();    //illegal
      //a.packageMethod();    //illegal
      //a.protectedMethod();  //illegal
        a.publicMethod();     //legal

      //System.out.format("privateVariable:   %2d%n",
      //  a.privateVariable);       //illegal
      //System.out.format("packageVariable:   %2d%n",
      //  a.packageVariable);       //illegal
      //System.out.format("protectedVariable: %2d%n",
      //  a.protectedVariable);   //illegal
        System.out.format("publicVariable:    %2d%n",
          a.publicVariable);         //legal
    }
}
Here's the output from DeltaTwo:
publicMethod called
publicVariable: 4

Tips on Choosing an Access Level: 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. (Many of the examples in the tutorial use public member variables. This may help to illustrate some points concisely, but is not recommended for production code.) 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.
  • Limit the number of protected and package member variables.
  • If a member variable is a JavaBeansTM property, it must be private.


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.