- Java当中内部类主要有4种,分别是静态内部类、实例内部类/非静态内部类、局部内部类(几乎不用)、匿名内部类。
- 静态内部类:被static修饰的内部成员类
①在静态内部类只能访问外部类中的静态成员
②创建静态内部类对象时,不需要先创建外部类对象
public class OutClass {
public int a = 10;
private int b = 20;
public static int c = 30;
static class InnerClass {
public int d = 40;
public void func() {
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(outClass.b);
System.out.println(c);
System.out.println(d);
}
}
public static void main(String[] args) {
//实例化静态内部类对象
OutClass.InnerClass innerClass = new OutClass.InnerClass();
innerClass.func();
}
}
分析:a和b在外部类当中,为非静态成员变量,所以a和b必须通过外部类的引用才能访问【在静态内部类当中,不能直接访问外部类的非静态成员】,因为静态的都不依赖于对象,非静态的依赖对象,则在静态内部类中实例化外部类的对象,在静态内部类中通过外部类的引用来访问外部类的非静态成员变量。
③外部类当中可以访问静态内部类中的所有成员,哪怕是private修饰的,new内部类对象,通过引用访问即可。
public class OutClass {
static class InnerClass {
private int h = 6;
}
public void fun(){
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.h);
}
}
生成的字节码文件:每一个类是一个字节码文件。外部类类名$内部类类名.class
- 实例内部类/非静态内部类:即未被atatic修饰的成员内部类
①在实例内部类中,不能定义静态的成员变量
【如果非要定义,加个final,变成常量,因为常量是在程序编译的时候,就能确定的】
public class OutClass {
public int a = 1;
private int b = 2;
public static int c = 3;
class InnerClass { //依赖于对象的
public int d = 4;
private int e = 5;
//会报错,因为InnerClass的产生一定是会依赖于OutClass对象的,而f的产生不依赖于对象
// public static int f = 6;
public static final int f = 6;
}
}
②拿到实例内部类对象
public static void main(String[] args) {
// InnerClass innerClass = new InnerClass(); //报错,不可以
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass = outClass.new InnerClass();
}
要先拿到外部类对象,再创建实例内部类对象(实例内部类比较麻烦,需要外部类对象)
③内部类中有a=11111,外部类中有a=1,最后再内部类中输出打印a,会打印出内部类的11111。
package demo2;
public class OutClass {
public int a = 1;
private int b = 2;
public static int c = 3;
class InnerClass { //依赖于对象的
public int d = 4;
private int e = 5;
public int a = 111111;
//会报错,因为InnerClass的产生一定是会依赖于OutClass对象的,而f的产生不依赖于对象
// public static int f = 6;
public static final int f = 6;
public void func() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println(e);
}
}
public void fun() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
InnerClass innerClass = new InnerClass();
System.out.println(innerClass.d);
System.out.println(innerClass.e);
}
public static void main(String[] args) {
// InnerClass innerClass = new InnerClass(); //报错,不可以
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass = outClass.new InnerClass();
innerClass.func();
}
}
要想访问外部的a,则 System.out.println(OutClass.this.a);
,说明在非静态内部类当中,包含外部类的this,即实力内部类包含2个this。OutClass.this.a
代表外部类的a,this.a
代表内部类的a。
- 匿名内部类
interface IA {
void func();
}
class AA implements IA{
public void func() {
System.out.println("hhh");
}
}
public class Test{
public static void main(String[] args) {
// IA ia = new AA();
// ia.func();
new IA(){
@Override
public void func() {
System.out.println("hhh");
}
};
}
}
分析:new接口,在其后加花括号,然后重写了func方法==和AA类等价,但是这个类没有名字,所以叫匿名内部类,不会产生字节码文件。
- 局部内部类:在方法里定义的类,不常用。