静态内部类与普通内部类的区别

百般思念 提交于 2020-02-25 19:52:23

今天接到一个需求,是将公司的一些统计数据文件内容解析出来后,通过mq发给用户运营平台,给公司的大佬看,这个还是很简单,半个小时就码完了,但自测完后突然发现怎么建了这么多DTO(data transform object)!因为统计文件有很多不同类型,我针对每个类型都建了相应的DTO,因为这个DTO在其他业务也用不上,而且以后文件类型还有增加的话,那DTO也会增加,仅仅因为这单个小功能产生这么多利用率不高的DTO着实不太好(论项目是如何变臃肿的),所以我想到了一个办法,建一个外部类,然后将这些文件对应的DTO作为内部类放在里面。但是内部类是用普通类还是静态类呢?其实我也不知道,所以我好好研究了一番他们的区别。

我先贴下网上找到的关于普通内部类和静态内部类的区别:

  1. 普通内部类持有对外部类的引用,静态内部类没有持有外部类的引用。

  2. 普通内部类能够访问外部类的静态和非静态成员,静态内部类不能访问外部类的非静态成员,他只能访问外部类的静态成员。

  3. 一个普通内部类不能脱离外部类实体被创建,且可以访问外部类的数据和方法,因为他就在外部类里面。


是不是一脸懵逼,哪里引用了外部类?我怎么没看见?其实我看完后也是一脸懵逼,后来我猜想,这些是不是jvm将java文件编译成class文件的过程中帮我们做了点手脚?为了验证猜想,于是乎做了下面实验。

我先写了一个很简单的普通内部类和静态内部类的代码:

package com.yy.demo15_innerClass;

/**
 * @Author: 24只羊
 * @Date: 2020-02-24
 */
public class OuterClass {

    // 普通成员变量
    private String outField = "out field";
    // 静态成员变量
    private static String outStaticField = "out static field";

    // 普通内部类
    public class InnerClassA{
    }
    // 静态内部类
    public static class InnerStaticClassB{
    }
}

我们在idea或eclipse编译这个类所在的项目后,这个OuterClass.java会生成三个Class文件:

OuterClass.class

OuterClass$InnerClassA.class

OuterClass$InnerStaticClassB.class

这个三个文件夹内容是啥呢?我们可以通过反编译看看(我用的是在线反编译,链接贴文末了)

反编译后生成了:

OuterClass.java

OuterClass$InnerClassA.java

OuterClass$InnerStaticClassB.java

package com.yy.demo15_innerClass;

public class OuterClass {
   private String outField = "out field";
   private static String outStaticField = "out static field";
}
package com.yy.demo15_innerClass;

import com.yy.demo15_innerClass.OuterClass;

public class OuterClass$InnerClassA {

   // $FF: synthetic field
   final OuterClass this$0;

   public OuterClass$InnerClassA(OuterClass this$0) {
      this.this$0 = this$0;
   }
}
package com.yy.demo15_innerClass;

public class OuterClass$InnerStaticClassB {

}

我们可以看到普通内部类InnerClassA在编译成class文件后,其自动在class文件中引用了外部类OuterClass,而内部静态类则没有引用外部类。

这样普通内部类相比外部内部类有个好处——就是可以引用外部类的属性以及方法。但凡事有两面,因为内部类里面持有外部类的引用,如果内部类一直在执行,则外部类就不会被GC回收,如果外部类中含有大量资源,有可能会导致内存泄漏(安卓中比较常见,比如外部类中有大量图片啥的,但是java后端这种情况的场景我还没想到,可能太菜了吧!!!),所以担心内存泄漏,就用静态内部类吧。嗯嗯,我的需求也是用的静态内部类。

现在我们再看看本文开头的总结,是不是一目了然!

最后贴下我用的在线反编译链接地址:http://javare.cn/

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!