内部类隐式持有外部类
Posted 清浅岁月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类隐式持有外部类相关的知识,希望对你有一定的参考价值。
内部类隐式持有外部类
源码
package com.example.testdemo;
public class OutClass
int out =2;
public class InnerClass
int in=1;
编译成.class文件,有两个文件
内部类InnerClass
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.testdemo;
public class OutClass$InnerClass
int in;
// 构造方法需要传入OutClass这个对象
public OutClass$InnerClass(OutClass var1)
this.this$0 = var1;
this.in = 1;
外部类:OutClass
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.testdemo;
public class OutClass
int out = 2;
public OutClass()
public class InnerClass
int in = 1;
public InnerClass()
静态内部类
看一下加了static的静态内部类是什么样子:
源码
package com.example.testdemo;
public class OutClass
int out =2;
public static class InnerClass
int in=1;
编译成.class文件,有两个文件
InnerClass内部类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.testdemo;
public class OutClass$InnerClass
int in = 1;
public OutClass$InnerClass()
OutClass外部类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.example.testdemo;
public class OutClass
int out = 2;
public OutClass()
public static class InnerClass
int in = 1;
public InnerClass()
总结:
1.内部类编译成.class文件后,构造方法需要传递外部类进来,this.this=外部类,导致内部类持有一个外部类。
2.内部类被static后,没有该参数,所以内部类不再持有
内部类和静态内部类的加载
package com.example.testdemo;
import java.util.Random;
public class OutClass
public static long OUTER_DATE = System.currentTimeMillis();
static
System.out.println("外部类静态块加载时间:" + System.currentTimeMillis());
public OutClass()
System.out.println("外部类构造时间:" + System.currentTimeMillis());
public static class InnerStaticClass
public static long INNER_STATIC_DATE = System.currentTimeMillis();
class InnerClass
public long INNER_DATE = 0;
public InnerClass()
INNER_DATE = System.currentTimeMillis();
public static void outerStaticMethod()
System.out.println("外部类静态方法执行了");
timeElapsed();
System.out.println("打印时间:" + System.currentTimeMillis() + ".....静态内部类加载时间:" + OutClass.InnerStaticClass.INNER_STATIC_DATE);
timeElapsed();
System.out.println("打印时间:" + System.currentTimeMillis() + ".....外部类静态变量加载时间:" + OutClass.OUTER_DATE);
timeElapsed();
System.out.println("打印时间:" + System.currentTimeMillis() + ".....调用外部静态方法:" ) ;OutClass.outerStaticMethod();
timeElapsed();
OutClass student1 = new OutClass();
System.out.println("打印时间:" + System.currentTimeMillis() + ".....非静态内部类加载时间:" + student1.new InnerClass().INNER_DATE);
执行时间
System.out: 打印时间:1599647679473.....静态内部类加载时间:1599647679473
System.out: 外部类静态块加载时间:1599647680938
System.out: 打印时间:1599647680938.....外部类静态变量加载时间:1599647680938
\\
System.out: 打印时间:1599647682310.....调用外部静态方法:
System.out: 外部类静态方法执行了
System.out: 外部类构造时间:1599647683675
System.out: 打印时间:1599647683675.....非静态内部类加载时间:1599647683675
总结:
静态变量,静态方法,静态块等都是类级别的属性,而不是单纯的对象属性。他们在类第一次被使用时被加载(记住,是一次使用,不一定是实例化)。我们可以简单得用 类名.变量 或者 类名.方法来调用它们。与调用没有被static 修饰过变量和方法不同的是:一般变量和方法是用当前对象的引用(即this)来调用的,静态的方法和变量则不需要。从一个角度上来说,它们是共享给所有对象的,不是一个角度私有。这点上,静态内部类也是一样的。
静态内部类的加载过程:
静态内部类的加载不需要依附外部类,在使用时才加载
所以静态holder的单例:
package com.example.testdemo;
public class SingleInstence
private SingleInstence()
// 防止反射入侵外部类
if (SingleInstenceHolder.mSingleInstence != null)
throw new IllegalStateException();
public static SingleInstence instence()
return SingleInstenceHolder.mSingleInstence;
private static class SingleInstenceHolder
private static final SingleInstence mSingleInstence = new SingleInstence();
以上是关于内部类隐式持有外部类的主要内容,如果未能解决你的问题,请参考以下文章