java内部匿名类
前言:
java基础的编写类的时候,会觉得很匿名内部类很神秘.普通的java文件会被编译成class,那内部类和匿名内部类呢?它们被会存在在哪个物理位置?
本文主要针对匿名内部类.
本文中有ISay和ISay2两个接口,用于测试对比.
ISay.java
public interface ISay {
void sayHello();
}
ISay2.java
public interface ISay2 {
void sayHello222();
void print();
}
Program.java
public class Program {
public static void main(String[] args) {
ISay say = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay say2 = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay say3 = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay2 say2_1 = new ISay2() {
public void sayHello222() {
System.out.println("Hello java!");
}
public void print(){
System.out.print("print");
}
};
say.sayHello();
say2.sayHello();
say2_1.sayHello222();
say2_1.print();
}
}
生成的class文件如下图:
ISay.java
public interface ISay {
void sayHello();
}
ISay2.java
public interface ISay2 {
void sayHello222();
void print();
}
Program.java
public class Program {
public static void main(String[] args) {
ISay say = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay say2 = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay say3 = new ISay() {
public void sayHello() {
System.out.println("Hello java!");
}
};
ISay2 say2_1 = new ISay2() {
public void sayHello222() {
System.out.println("Hello java!");
}
public void print(){
System.out.print("print");
}
};
say.sayHello();
say2.sayHello();
say2_1.sayHello222();
say2_1.print();
}
}
生成的class文件如下图:
发现会有Program$1.class等文件,其实这就是匿名类的class文件.
使用jclasslib查看Program.class字节码
###是注释,不是字节码的内容
new #2 <NewInterface/Program$1> ###对应代码ISay say = new Program$1() ,Program$1是ISay的实现。
dup
invokespecial #3 <NewInterface/Program$1.<init>>
astore_1 ###存放引用在变量1中
new #4 <NewInterface/Program$2>
dup
invokespecial #5 <NewInterface/Program$2.<init>>
astore_2
new #6 <NewInterface/Program$3>
dup
invokespecial #7 <NewInterface/Program$3.<init>>
astore_3
new #8 <NewInterface/Program$4>
dup
invokespecial #9 <NewInterface/Program$4.<init>>
astore 4
aload_1 ###加载本地变量1的引用,即上述的NewInterface/Program$1
invokeinterface #10 <NewInterface/ISay.sayHello> count 1 ###调用方法,对象是本地变量1的实例。
aload_2
invokeinterface #10 <NewInterface/ISay.sayHello> count 1
aload 4 ###加载本地变量4的引用,即上述的NewInterface/Program$4
invokeinterface #11 <NewInterface/ISay2.sayHello222> count 1 ###调用方法,对象是本地变量4的实例。
aload 4
invokeinterface #12 <NewInterface/ISay2.print> count 1
return
内部类跟匿名内部类的class生成规则差不多,只不过匿名内部类是由编译器命令,内部类是直接指定.
例如:Program中有一个内部类叫Book,那么生成的class文件是Program$Book.class