当前位置: 首页 > news >正文

Java内部类

在一个类的内部再定义一个类,所以称为内部类

内部类主要有几种:成员内部类局部内部类静态内部类匿名内部类

成员内部类

一个类中直接定义的内部类,可以理解为类的普通成员。

而作为类的成员,成员内部类可以无限制地访问外部类的所有成员(属性 + 方法)。


但有一点特别的是,成员内部类的实例不能单独存在,必须依附于一个外部类的实例

即要实例化一个成员内部类,必须首先创建一个外部类的实例,然后调用外部类实例的 new 来创建内部类实例 outer.new Inner()

这其实也很好理解,因为类的成员就是要依附于具体的实例的

// inner class
public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer("Nested"); // 实例化一个Outer
        Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
        inner.hello();
    }
}

class Outer {
    private String name;

    Outer(String name) {
        this.name = name;
    }

    class Inner {
        void hello() {
            System.out.println("Hello, " + Outer.this.name);
        }
    }
}

静态内部类(嵌套类)

与成员内部类类似、也是定义在类中,只是多了 static 修饰。

因此与成员内部类所不同的是,静态内部类不再依附于外部类的实例,可以独立地实例化,是一个完全独立的类。

但是,它只可以访问外部类 静态的属性和方法。

// Static Nested Class
public class Main {
    public static void main(String[] args) {
        Outer.StaticNested sn = new Outer.StaticNested();
        sn.hello();
    }
}

class Outer {
    private static String NAME = "OUTER";

    private String name;

    Outer(String name) {
        this.name = name;
    }

    static class StaticNested {
        void hello() {
            System.out.println("Hello, " + Outer.NAME);
        }
    }
}

局部内部类

在方法中定义的内部类称为局部内部类

与局部变量类似,局部内部类不能有访问说明符,因为它不是外围类的一部分。

但是它可以访问当前代码块内的常量,和外部类所有的成员


局部内部类的生命周期只限于定义该内部类的方法,只能在此方法内实例化,不可以在此方法外对其实例化。

public class Outer {
    private static int number = 100;
    private int j = 20;
    private String name = "Java";

    //定义外部类方法
    public void outer_funOne(int k){
        final int number = 100;
        int j = 50;

        //方法内部的类(局部内部类)
        class Demo{
            public Demo(int k){
                demo_funOne(k);
            }

            int number = 300; //可以定义与外部类同名的变量
            // static int j = 10;  //不可以定义静态变量

            //内部类的方法
            public void demo_funOne(int k){
                System.out.println("内部类方法:demo_funOne");
                //访问外部类的变量,如果没有与内部类同名的变量,则可直接用变量名
                System.out.println(name);
                //访问外部类与内部类同名的变量
                System.out.println(Outer.this.number);
                System.out.println("内部类方法传入的参数是:"+k);
            }
        }

        new Demo(k);
    }




    public static void main(String[] args) {
        //访问内部类必须要先有外部类对象
        Outer out = new Outer();
        out.outer_funOne(11);
    }

}

匿名内部类

匿名内部类 是定义在方法中的,其语法为 new 某个接口或者类、并在后面加上类的定义

其实是 首先定义了一个匿名类、该类实现某个接口或继承某个类,并在定义后马上实例化了这个匿名类


与局部内部类一样,可以访问当前代码块内的常量,和外部类所有的成员

class Outer {
    private String name;

    Outer(String name) {
        this.name = name;
    }

    void asyncHello() {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello, " + Outer.this.name);
            }
        };
        new Thread(r).start();
    }
}

日常开发用的最多的场景就是,用匿名内部类来实现函数式接口,并且通常是使用Lambda 表达式来简化代码。

如以上例子的匿名内部类就是实现了函数式接口 Runnable。

函数式接口:只有一个抽象方法的接口。

匿名类也可以继承自普通类

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> map1 = new HashMap<>();
        HashMap<String, String> map2 = new HashMap<>() {};
        HashMap<String, String> map3 = new HashMap<>() {
            {
                put("A", "1");
                put("B", "2");
            }
        };
        System.out.println(map3.get("A"));
    }
}

map1 是一个普通的 HashMap 实例。

map2 是一个匿名类实例,只是该匿名类继承自 HashMap,并且类定义为空。

map3 也是一个继承自 HashMap 的匿名类实例,并且添加了构造代码块来初始化数据。

构造代码块:构造函数之前执行,并且每次实例化都会执行。

相关文章:

  • 【STM32】uwTick在程序中的作用及用法,并与Delay函数的区别
  • redis三主三从集群部署
  • Logic-RL:小参数qwen模型复现DeepSeek R1 zero
  • 自学软硬件第755 docker容器虚拟化技术
  • 图解Spring-解决循环依赖流程
  • 使用 OpenSSL 构建安全的网络应用
  • 前端开发概论
  • 网易云信架构升级实践,故障恢复时间缩至8秒
  • TDengine 支持的所有运算符
  • 零基础学python+人工智能ai(持续更新ing)
  • 【MySQL】基本查询(下)
  • 什么是MCP(Model Context Protocol)?对话、意图识别、服务调用和上下文管理
  • django self.get_queryset() 如何筛选
  • Flask实时监控:打造智能多设备在线离线检测平台(升级版)
  • 素数判定方法详解:从基础试除法到优化策略
  • linux系统 Ubuntu22.04安装Nvidia驱动,解决4060系列显卡重启黑屏方法
  • c语言笔记 结构体内嵌套结构体的表示方式
  • 二维前缀矩阵
  • 十七、实战开发 uni-app x 项目(仿京东)- 后端指南
  • 5.0 VisionPro调用USB相机的方法与步骤说明(一)
  • 被围观的“英之园”,谁建了潮汕天价违建?
  • 雅安市纪委监委回应黄杨钿甜耳环事件:相关政府部门正在处理
  • 第十届曹禺剧本奖上海揭晓,首次开放个人申报渠道
  • 专访|《内沙》导演杨弋枢:挽留终将失去的美好
  • 上海博物馆展览进校园,“小先生”传递文物知识
  • 奥运“四朝元老”华天回国参赛,伤势未愈谨慎出战全国锦标赛