注意错误信息。它并没有说你“没有访问权”。它说的是方法“无法被调用”。没有实例调用它们,实例方法是毫无意义的。错误信息告诉你的是你没有那个实例。
Bloch 告诉你的是,如果存在那个实例,内部类中的代码可以调用其私有实例方法。
假设我们有以下的类:
public class OuterClass {
public void publicInstanceMethod() {}
public static void publicClassMethod() {}
private void privateInstanceMethod() {}
private static void privateClassMethod() {}
}
如果我们试图从某个随机类调用这些私有方法,是无法做到的:
class SomeOtherClass {
void doTheThing() {
OuterClass.publicClassMethod();
OuterClass.privateClassMethod();
}
void doTheThingWithTheThing(OuterClass oc) {
oc.publicInstanceMethod();
oc.privateInstanceMethod();
}
}
请注意,这些错误信息显示为“私有访问”。
如果我们在OuterClass本身中添加一个方法,就可以调用这些方法:
public class OuterClass {
private void doAThing() {
publicInstanceMethod();
privateInstanceMethod();
publicClassMethod();
privateClassMethod();
}
}
或者如果我们添加一个静态内部类:
public class OuterClass {
private static class StaticInnerClass {
private void doTheThingWithTheThing(OuterClass oc) {
publicClassMethod();
privateClassMethod();
oc.publicInstanceMethod();
oc.privateInstanceMethod();
publicInstanceMethod();
privateInstanceMethod();
}
}
}
如果我们添加一个非静态内部类,似乎就可以实现魔法:
public class OuterClass {
private class NonStaticInnerClass {
private void doTheThing() {
publicClassMethod();
privateClassMethod();
publicInstanceMethod();
privateInstanceMethod();
}
}
}
然而,这里存在一些技巧:非静态内部类总是与外部类的一个实例相关联,你真正看到的是:
private class NonStaticInnerClass {
private void doTheThing() {
publicClassMethod();
privateClassMethod();
OuterClass.this.publicInstanceMethod();
OuterClass.this.privateInstanceMethod();
}
}
在这里,OuterClass.this
是访问外部实例的特殊语法。但只有当它是不明确的时候才需要使用它,例如当外部类和内部类具有相同名称的方法时。
还要注意,非静态类仍然可以执行静态类能够执行的操作:
private class NonStaticInnerClass {
private void doTheThingWithTheThing(OuterClass oc) {
oc.publicInstanceMethod();
oc.privateInstanceMethod();
}
}
简而言之:
public
和
private
一直是关于
访问权限的。 Bloch所说的重点是内部类具有其他类没有的访问权限。但是无论有多少访问权限,都不能在不告诉编译器要调用哪个实例方法的情况下调用实例方法。