一文带你真正理解Java中的内部类

作者:JAVA旭阳 时间:2023-11-24 20:42:07 

概述

不知道大家在平时的开发过程中或者源码里是否留意过内部类,那有思考过为什么要有内部类,内部类都有哪几种形式,静态内部类和普通内部类有什么区别呢?本篇文章主要带领大家理解下这块内容。

内部类介绍和分类

顾名思义,内部类是指一个类在另外一个类的内部,是定义在另一个类中的类。根据类的位置和属性不同,可以分为下面几种。

常规内部类

@Data
public class Tree {

private String treeName;

private String treeType;

private List<Leaf> leafs;

@Data
   public class Leaf {
       private String color;

private String leafSize;

public void show() {
           System.out.println("tree name: " + Tree.this.treeName);
           System.out.println("tree name: " + treeName);
       }
   }

public static void main(String[] args) {
       Tree tree = new Tree();
       Leaf leaf = tree.new Leaf();
   }
}

上面就是一个内部类的例子,Leaf是Tree的内部类。

  • 内部类中可以直接访问外部类的数据,包括私有数据。

  • 常规内部类中的方法或者字段不能是静态的。

  • 内部类中可以使用如下的语法Tree.this.treeName

  • 内部类创建对象需要外部对象的存在,如下:

Tree tree = new Tree();
Leaf leaf = tree.new Leaf();

字节码分析:

我们查看下内部类的字节码,如下图:

一文带你真正理解Java中的内部类

我们看到内部类Leaf的构造方法init,实际上会隐式地将外部对象传入,初始化,这样才能在内部类中访问。

局部内部类

局部内部类,比如只有在一个方法内部创建。

@Data
public class Tree {

private String treeName;

private String treeType;

private List<Leaf> leafs;

public void treeRoot(int height) {
       class TreeRoot {
           private int rootHeight;

public void showRootHeight() {
               this.rootHeight = height;
               System.out.println("root height " + height);
           }
       }
       TreeRoot root = new TreeRoot();
       root.showRootHeight();
   }
}
  • 局部类不能用public或private访问说明符进行声明,因为作用域只在这个局部,没有必要。

  • 局部内部类可以完全将自己隐藏起来,体现良好的封装性。

  • 局部内部类可以直接访问方法的变量。

匿名内部类

匿名内部类,就更加简洁了,连类名都省略了, 这个配合lambda食用,非常简便,想必大家也经常使用了。

public static void main(String[] args) {
       Runnable runnable = new Runnable() {
           @Override
           public void run() {
               System.out.println("runnable");
           }
       };

Runnable runnable2 = () -> System.out.println("runnable");
   }

匿名内部类也体现了良好的封装性和简洁性。

静态内部类

最后,再介绍下静态内部类,这个也使用的非常频繁。java源码中也有很多这样的例子,比如HashMap中,Node节点就是一个静态内部类。

一文带你真正理解Java中的内部类

如果用static来修饰一个内部类,那么就是静态内部类。这个内部类属于外部类本身,但是不属于外部类的任何对象。因此使用static修饰的内部类称为静态内部类。静态内部类有如下规则:

  • 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。

  • 外部类可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象访问其实例成员。

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

我们可以通俗按下面的方式理解:

内部类:就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的)

静态内部类:就是我跟你没关系,自己可以完全独立存在,但是我就借你的壳用一下,来隐藏自己。

从字节码角度上看,静态内部类和非静态内部类最大的区别是:非静态内部类编译后隐式保存着外部类的引用(就算外部类对象没用了也GC不掉),但是静态内部类没有。

内部类的作用

通过上面的了解,我想内部类还是有一定的意义的。

  • 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。

  • 内部类可以对同一个包中的其他类隐藏起来。

其实内部类更多的时候,不想把这个类暴露出去,它可能只是外部类的一个逻辑组成部分,不需要其他地方知道什么,这时候我们用内部类更加的清楚。

来源:https://juejin.cn/post/7137699156973322247

标签:Java,内部类
0
投稿

猜你喜欢

  • Java中switch的三种用法方式小结

    2023-11-24 03:40:21
  • Base64编码解码原理及C#编程实例

    2022-05-07 03:58:53
  • Android应用开发中Fragment间通信的实现教程

    2023-02-23 18:06:46
  • Java特性队列和栈的堵塞原理解析

    2023-10-13 14:15:55
  • IDEA下载并大学生edu邮箱认证免费使用教程(图文)

    2022-10-10 14:23:02
  • 深入理解Android中的建造者模式

    2023-06-27 05:55:17
  • SchedulingConfigurer实现动态定时,导致ApplicationRunner无效解决

    2021-12-01 11:26:10
  • git版本回退_动力节点Java学院整理

    2022-06-21 13:26:10
  • java算法之Math.random()随机概率玩法实例演示

    2023-11-28 23:32:17
  • Java代码实现酒店管理系统

    2023-08-13 13:09:23
  • Android开发解决字符对齐问题方法

    2022-09-15 18:26:15
  • Android实现图片缓存与异步加载

    2022-02-25 14:21:06
  • 如何解决springboot读取配置文件的中文乱码问题

    2022-09-13 22:26:42
  • SpringBoot多种自定义错误页面方式小结

    2021-12-12 00:56:03
  • Android Handler消息机制分析

    2023-10-01 13:22:26
  • Android使用插件实现代码混淆

    2023-02-25 07:13:10
  • java.net.ConnectException: Connection refused问题解决办法

    2023-11-28 18:49:52
  • 深入理解spring boot 监控

    2023-11-04 02:25:15
  • C#使用Dispose模式实现手动对资源的释放

    2022-09-21 16:12:14
  • 解决C#中Linq GroupBy 和OrderBy失效的方法

    2022-11-21 00:25:11
  • asp之家 软件编程 m.aspxhome.com