内部类分
- 内部类:有名字的
- 匿名内部类:没有名字的
- 局部类:在方法块中定义并且随随着方法块销毁
命名规则
- 内部类:outerclass$innerclass
- 匿名内部类:outerclass${number}
- 局部类:outerclass${number}{innerclass},这里number是从1开始当innerclass重名时会增加
==内部类不允许有静态变量但是允许有静态常量==
==类都是同级==的,实质上所有编译的内部类都会被推出外部类和外部类同级,只是名字上做一下嵌套。
public class Main
{
public class A{
private String a;
public void say(){
System.out.println("dasda");
}
}
public void p(){
new A().say();
}
}
编译后会出现
Main.class
Main$A.class
但是如果把内部类改成私有的话,如:
public class Main
{
private class A{
private String a;
public void say(){
System.out.println("dasda");
}
}
public void p(){
new A().say();
}
}
那编译结果会变成
Main.class
Main$A.class
Main$1.class
这个时候会多一个匿名内部类
当你做反编译时候你会发现A会生成一个默认构造函数
private A(Main var1){}
其中传入参数var1会保存到A的内部属性以达到内部类能访问外部类。
默认生成的是private的构造函数,但是同级情况下Main又是为什么能访问一个私有构造函数呢,其实是还有一个构造函数是
A(Main var1,Main$1 var2){
this(var1);
}
就是一个语法糖,通过重载生成一个新的构造函数来创建A而不是直接调用A的构造函数,这里有个匿名内部类Main$1是为了防止和开发者自己写的方法冲突。
而内部类的私有方法的访问其实是在内部类下创建访问器来进行访问的,如上面的例子中的A.a会有一个方法叫做
static String access$0000(A var1){
return var1.a;
}
这样来做区分的