package pack;
class OffLimits { // Note this has default access
public int x = 11;
}
public class Allowed extends OffLimits {}
package outside;
import pack.*;
public class Outsider extends Allowed {
public static void main(String[] args) {
System.out.println((new
Outsider()).x);
}}
This program is legal, and yet, if we compile it according to the directives in JLS 13.1, it will fail to execute on a Java virtual machine because it violates the rules for access control. Specifically, the expression
(new Outsider()).xwill be compiled as a symbolic reference to the declaring class of x, pack.OffLimits. When resolving this symbolic reference, the Java virtual machine will raise an IllegalAccessError, because the class pack.OffLimits is not accessible from the class outside.Outsider. Under the corrected rule, the code executes correctly.
Another benefit of the revised rules is that the structure of the inheritance graph of a class is hidden from its clients. This enables additional binary compatible changes. For example, fields and methods can be moved up and down the hierarchy. As long as a class continues to expose a field or method to its clients, those clients will function regardless of where the field or method is declared.
Unfortunately, on older virtual machines such as the JDK1.0.2 VM, this
strategy is
unacceptable, because such VMs do not perform a link time search up
the hierarchy.
Therefore, this strategy applies to compilers targeted at VMs that
do perform such a link time search (such as the JDK 1.1 and JDK 1.2 VMs).
|
|