前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为啥非静态内部类能持有外部类?

为啥非静态内部类能持有外部类?

原创
作者头像
笔头
发布2022-02-23 18:54:51
9980
发布2022-02-23 18:54:51
举报
文章被收录于专栏:Android记忆

上次写了一篇关于内存泄漏的文章,里面涉及到一个说法,内部类会持有外部类的引用,静态内部类不会持有。这个说法在网上流传甚广。这个说法可能是对的,但是我们还不清楚他们为什么都这么说的。

一、非静态内部类

我们来看个例子

代码语言:javascript
复制
public class Outer {
    private String TAG="Outer";
    private Runnable runnable = new Runnable(){
        public void run(){
            System.out.println("inner run: " + TAG);
        }
    };
}

通过javac Outer.java 我们得到两个class文件

Outer.class

代码语言:javascript
复制
public class Outer {
    private String TAG = "Outer";
    private Runnable runnable = new Runnable() {
        public void run() {
            System.out.println("inner run: " + Outer.this.TAG);
        }
    };

    public Outer() {
    }
}

Outer$1.class

代码语言:javascript
复制
class Outer$1 implements Runnable {
    Outer$1(Outer var1) {
        this.this$0 = var1;
    }

    public void run() {
        System.out.println("inner run: " + this.this$0.TAG);
    }
}

在Outer$1.class中,Outer$1是Runnable,我们可以看到在Outer$1类函数中,传了外部类Outer对象,this.this$0是指向Outer对象。Outer$1持有Outer,也就是Runnable持有Outer。

二、静态内部类

如果我们把Runnable改成静态的看下。

代码语言:javascript
复制
public class Outer {
    private static String TAG="Outer";
    private static Runnable runnable = new Runnable(){
        public void run(){
            System.out.println("inner run: " + TAG);
        }
    };
}

通过javac Outer.java命令

我们看到Outer$1.class

代码语言:javascript
复制
class Outer$1 implements Runnable {
    Outer$1() {
    }
    public void run() {
        System.out.println("inner run: " + Outer.TAG);
    }
}

我们可以得到Outer$1并没有Outer,所以静态内部类不持有外部类。

为啥静态内部类不能持有外部类?因为它是静态的,所以它引用的外部类的变量也必须是静态对象。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、非静态内部类
  • 二、静态内部类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档