思考以下代码的输出是什么?
Runnable x = new Runnable() {
@Override
public void run() {
System.out.println(this.getClass());
}
};
x.run();
匿名类相当于在定义类的同时再新建这个类的实例。我们来看看匿名类的编译结果。
这个类的代码如下:
public class Test {
public void test() {
Runnable r = new Runnable(){
@Override
public void run(){
System.out.println("hello");
}
};
}
}
SourceFile: "Test.java"
EnclosingMethod: #20.#21 // Test.test
InnerClasses:
#6; //class Test$1
#21 = NameAndType #34:#16 // test:()V
Runnable hello = new Runnable() {
public void run() {
System.out.println("hello");
}
};
public class A {
private int foo;
public void test() {
Runnable r = new Runnable() {
System.out.println(foo);
};
}
}
匿名类里面不可以有的东西:
public class A {
public void test() {
Runnable r = new Runnable() {
static { System.out.println("hello"); }
};
}
}
2. 不能在匿名类里面定义接口。
public class A {
public void test() {
Runnable r = new Runnable() {
public interface Hello { };
};
}
}
public class A {
public void test() {
Runnable r = new Runnable() {
public Runnable() { }
};
}
}
public class A {
public class B {
}
}
它编译之后,会变成下面这种含义:
public class A {
public static class B {
private final A parent;
public B(A parent) {
this.parent = parent;
}
}
}
所以,按照这么说,内部类就是一种语法糖。
public class A {
private int a;
public class B {
public static void test() {
a = 1;
}
}
}
但是编译之后,问题就来了。
public class A {
private int a;
public static class B {
private final A parent;
public B (A parent) { this.parent = parent; }
public static void test() {
parent.a = 1; // 这里有语法错误
}
}
}