我们看下面的类声明
public class Foo { private int mValue; public void run() { Inner in = new Inner(); mValue = 27; in.stuff(); } private void doStuff(int value) { System.out.println("Value is " + value); } private class Inner { void stuff() { Foo.this.doStuff(Foo.this.mValue); } } }
这里我们要注意的是我们定义了一个内联类,它调用了外部类的私有方法和私有属性。这是合法的调用,代码应该会显示"Value is 27"。
问题是Foo$Inner在理论上(后台运行上)是应该是一个完全独立的类,它违规的调用了Foo的私有成员。为了弥补这个缺陷,编译器产生了一对合成的方法:
/*package*/ static int Foo.access$100(Foo foo) { return foo.mValue; } /*package*/ static void Foo.access$200(Foo foo, int value) { foo.doStuff(value); }
当内联类需要从外部访问“mValue”和调用“doStuff”时,内联类就会调用这些静态的方法,这就意味着你不是直接访问类成员,而是通过公共的方法来访问的。前面我们谈过间接访问要比直接访问慢,因此这是一个按语言习惯无形执行的例子。
让拥有包空间的内联类直接声明需要访问的属性和方法,我们就可以避免这个问题,哲理诗是包空间而不是私有空间。这运行的更快并且去除了生成函数前面东西。(不幸的是,它同时也意味着该属性也能够被相同包下面的其他的类直接访问,这违反了标准的面向对象的使所有属性私有的原则。同样,如果是设计公共的API你就要仔细的考虑这种优化的用法)