CHAPTER 6: Names Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

6.6 Qualified Names and Access Control

6.6.1 Determining Accessibility , 6.6.2 Details on protected Access , 6.6.3 An Example of Access Control , 6.6.4 Example: Access to public and Non-public Classes , 6.6.5 Example: Default-Access Fields, Methods, and Constructors , 6.6.6 Example: public Fields, Methods, and Constructors , 6.6.7 Example: protected Fields, Methods, and Constructors , 6.6.8 Example: private Fields, Methods, and Constructors

Qualified names are a means of access to members of packages and reference types; related means of access include field access expressions (S15.10) and method invocation expressions (S15.11). All three are syntactically similar in that a ". " token appears, preceded by some indication of a package, type, or expression having a type and followed by an Identifier that names a member of the package or type. These are collectively known as constructs for qualified access.

Java provides mechanisms for access control, to prevent the users of a package or class from depending on unnecessary details of the implementation of that package or class. Access control applies to qualified access and to the invocation of constructors by class instance creation expressions (S15.8), explicit constructor invocations (S8.6.5), and the method newInstance of class Class (S20.3.6).

If access is permitted, then the accessed entity is said to be accessible.


6.6.1 Determining Accessibility


6.6.2 Details on protected Access

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object. Let C be the class in which a protected member or constructor is declared and let S be the subclass of C in whose declaration the use of the protected member or constructor occurs. Then:


6.6.3 An Example of Access Control

For examples of access control, consider the two compilation units:


package points;

class PointVec { Point[] vec; }

and:


package points;



public class Point {
	protected int x, y;
	public void move(int dx, int dy) { x += dx; y += dy; }
	public int getX() { return x; }
	public int getY() { return y; }
}

which declare two class types in the package points :

See S6.6.7 for an example of how the protected access modifier limits access.


6.6.4 Example: Access to public and Non-public Classes

If a class lacks the public modifier, access to the class declaration is limited to the package in which it is declared (S6.6). In the example:


package points;



public class Point {
	public int x, y;
	public void move(int dx, int dy) { x += dx; y += dy; }
}


class PointList {
	Point next, prev;
}

two classes are declared in the compilation unit. The class Point is available outside the package points , while the class PointList is available for access only within the package. Thus a compilation unit in another package can access points.Point , either by using its fully qualified name:


package pointsUser;



class Test {
	public static void main(String[] args) {
		points.Point p = new points.Point();
		System.out.println(p.x + " " + p.y);
	}
}

or by using a single-type-import declaration (S7.5.1) that mentions the fully qualfied name, so that the simple name may be used thereafter:


package pointsUser;


import points.Point;



class Test {
	public static void main(String[] args) {
		Point p = new Point();
		System.out.println(p.x + " " + p.y);
	}
}

However, this compilation unit cannot use or import points.PointList , which is not declared public and is therefore inaccessible outside package points .


6.6.5 Example: Default-Access Fields, Methods, and Constructors

If none of the access modifiers public , protected , or private are specified, a class member or constructor is accessible throughout the package that contains the declaration of the class in which the class member is declared, but the class member or constructor is not accessible in any other package. If a public class has a method or constructor with default access, then this method or constructor is not accessible to or inherited by a subclass declared outside this package.

For example, if we have:


package points;



public class Point {
	public int x, y;
	void move(int dx, int dy) { x += dx; y += dy; }
	public void moveAlso(int dx, int dy) { move(dx, dy); }
}

then a subclass in another package may declare an unrelated move method, with the same signature (S8.4.2) and return type, but because the original move method is not accessible from package morepoints super may not be used:


package morepoints;



public class PlusPoint extends points.Point {
	public void move(int dx, int dy) {
		super.move(dx, dy);								// compile-time error
		moveAlso(dx, dy);
	}
}

Because move of Point is not overridden by move in PlusPoint , the method moveAlso in Point never calls the method move in PlusPoint .

Thus if you delete the super.move call from PlusPoint and execute the test program:


import points.Point;

import morepoints.PlusPoint;

class Test {

    public static void main(String[] args) {
        PlusPoint pp = new PlusPoint();
        pp.move(1, 1);
    }

}

it terminates normally. If move of Point were overridden by move in PlusPoint , then this program would recurse infinitely, until a StackoverflowError occurred.


6.6.6 Example: public Fields, Methods, and Constructors

A public class member or constructor is accessible throughout the package where it is declared and from any other package that has access to the package in which it is declared (S7.4.4). For example, in the compilation unit:


package points;



public class Point {

	int x, y;


	public void move(int dx, int dy) {
		x += dx; y += dy;
		moves++;
	}


	public static int moves = 0;

}

the public class Point has as public members the move method and the moves field. These public members are accessible to any other package that has access to package points . The fields x and y are not public and therefore are accessible only from within the package points .


6.6.7 Example: protected Fields, Methods, and Constructors

Consider this example, where the point package declares:


package points;



public class Point {

	protected int x, y;


	void warp(threePoint.Point3d a) {
		if (a.z > 0)						// compile-time error: cannot access a.z
			a.delta(this);
	}

}

and the threePoint package declares:


package threePoint;


import points.Point;



public class Point3d extends Point {

	protected int z;


	public void delta(Point p) {
		p.x += this.x;						// compile-time error: cannot access p.x
		p.y += this.y;						// compile-time error: cannot access p.y
	}


	public void delta3d(Point3d q) {
		q.x += this.x;
		q.y += this.y;
		q.z += this.z;
	}

}

which defines a class Point3d . A compile-time error occurs in the method delta here: it cannot access the protected members x and y of its parameter p , because while Point3d (the class in which the references to fields x and y occur) is a subclass of Point (the class in which x and y are declared), it is not involved in the implementation of a Point (the type of the parameter p ). The method delta3d can access the protected members of its parameter q , because the class Point3d is a subclass of Point and is involved in the implementation of a Point3d .

The method delta could try to cast (S5.4, S15.15) its parameter to be a Point3d , but this cast would fail, causing an exception, if the class of p at run time were not Point3d .

A compile-time error also occurs in the method warp: it cannot access the protected member z of its parameter a , because while the class Point (the class in which the reference to field z occurs) is involved in the implementation of a Point (the type of the parameter a), it is not a subclass of Point (the class in which z is declared).


6.6.8 Example: private Fields, Methods, and Constructors

A private class member or constructor is accessible only within the class body in which the member is declared and is not inherited by subclasses. In the example:


class Point {

	Point() { setMasterID(); }


	int x, y;
	private int ID;
	private static int masterID = 0;

	private void setMasterID() { ID = masterID++; }

}

the private members ID, masterID , and setMasterID may be used only within the body of class Point . They may not be accessed by qualified names, field access expressions, or method invocation expressions outside the body of the declaration of Point .

See S8.6.8 for an example that uses a private constructor.

Top© 1996 Sun Microsystems, Inc. All rights reserved.