关于内部类的定义和使用,这里不做过多介绍,不太清楚的请先行了解。
自己写了一个类,里面有内部类和局部内部类。通过javac和javap去了解内部类的大体实现过程。
先附上代码
public class Use {
private String name;
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public class UseInner {
private String innerName;
public String getInnerName() {
return innerName;
}
public void setInnerName(String innerName) {
this.innerName = innerName;
}
public void testInner() {
System.out.println("out:" + name + "-" + age + "-" + innerName);
}
}
public String getSendChanenl() {
class Channel {
private Integer code;
private String name;
private UseInner useInner;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UseInner getUseInner() {
return useInner;
}
public void setUseInner(UseInner useInner) {
this.useInner = useInner;
}
}
Channel channel = new Channel();
channel.setCode(1);
channel.setName("XXX");
return channel.getCode() + channel.getName() + channel.getUseInner().getInnerName();
}
}
通过javac Use.java编译后,产生了3个class文件,他们分别是Use.class、Use$1Channel.class和Use$UseInner.class。
分别使用javap命令查看class文件信息。
javap -p Use
Compiled from "Use.java"
public class Use {
private java.lang.String name;
private java.lang.Integer age;
public Use();
public java.lang.Integer getAge();
public void setAge(java.lang.Integer);
public void setName(java.lang.String);
public java.lang.String getName();
public java.lang.String getSendChanenl();
static java.lang.String access$000(Use);
static java.lang.Integer access$100(Use);
}
上面有两个方法值得我们注意:
static java.lang.String access$000(Use); 为内部类提供外围类name属性的访问
static java.lang.Integer access$100(Use); 为内部类提供外围类age属性的访问
默认修饰符加static是当前方法只能在同一个包下访问。而内部类真是通过编译器生成一个同一个包下的类,来实现内部类。
javap -p Use\$1Channel.class
Compiled from "Use.java"
class Use$1Channel {
private java.lang.Integer code;
private java.lang.String name;
private Use$UseInner useInner;
final Use this$0;
Use$1Channel(Use);
public java.lang.Integer getCode();
public void setCode(java.lang.Integer);
public java.lang.String getName();
public void setName(java.lang.String);
public Use$UseInner getUseInner();
public void setUseInner(Use$UseInner);
}
这里把Use对象通过构造函数构造进来,就是为了能够访问外围类,且这里是final修饰的,对应唯一。
javap -p Use\$UseInner.class
Compiled from "Use.java"
public class Use$UseInner {
private java.lang.String innerName;
final Use this$0;
public Use$UseInner(Use);
public java.lang.String getInnerName();
public void setInnerName(java.lang.String);
public void testInner();
}
这个和上面的类似,也是把Use构造进来。
如果您有疑问,欢迎留言评论!