定义:类InnerClass是在类OutClass内部定义的,则类InnerClass称作是内部类,而类OutClass则称作是外部类。
1.普通内部类:定义分为两步,且内部类可以访问外部类的属性。
package innerClass;
//外部类
public class OutClass {
private String attribute = "外部类属性";//外部类的属性
//内部类
public class InnerClass{
private String attribute = "内部类属性";//内部类的属性
public void paint(){
String attribute = "局部变量";//局部变量
System.out.println(attribute);//局部覆盖原则
System.out.println(this.attribute);//通过this指针访问内部类属性
System.out.println(OutClass.this.attribute);//通过外部类.this指针访问外部类属性
}
}
public static void main(String[] args) {
//新建内部类对象分为两步
OutClass outClass = new OutClass();//首先创建外部类对象
InnerClass innerClass = outClass.new InnerClass();//再通过外部类对象.new 内部类的方式创建属于该外部类对象的内部类对象
innerClass.paint();
}
}
运行结果
2.静态内部类:static内部类是内部类中一个比较特殊的情况,Java文档中是这样描述static内部类的:一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类。也就是说,除了写在一个类的内部以外,static内部类具备所有外部类的特性。static内部类不仅可以在内部定义static元素,而且在构建对象的时候也可以一次完成。从某种意义上说,static内部类已经不算是严格意义上的内部类了。
package staticInnerClass;
//外部类
public class OutClass {
public static class StaticInnerClass{
public void fun(){
System.out.println("静态内部类可以定义普通属性和方法");
}
public static void staticFun(){
System.out.println("静态内部类也可以定义static属性和方法");
}
}
public static void main(String[] args) {
//静态内部类的定义可以一次性完成
OutClass.StaticInnerClass staticInnerClass = new OutClass.StaticInnerClass();
staticInnerClass.fun();
staticInnerClass.staticFun();
}
}
运行结果
3.使用静态内部类可以避免因使用内部类而造成内存泄漏,参考:https://blog.csdn.net/hejingyuan6/article/details/85989850
简而言之,普通的内部类会持有外部类的一个引用,当内部类与外部类的生命周期不一致时就有可能导致内存泄漏(外部类销毁的时候,内部类还有为完成的工作无法销毁,仍旧保留着对外部类的引用不释放,导致内存泄漏。)
这种情况下可以通过声明一个static的内部类来解决问题,从反编译中可以看出,声明为static的类不会持有外部类的引用,如果你想使用外部类的话,可以通过软引用的方式保存外部类的引用。