Java内部类
文章目录
- 一、内部类的概念
- 二、内部类的分析
- 三、内部类的分类
- 1. 成员内部类
- 2. 静态内部类
- 3. 局部内部类
- 4. 匿名内部类
- 匿名内部类与Lambda表达式
一、内部类的概念
在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。内部类的出现,再次打破了Java单继承的局限性。
内部类一般分为4种:成员内部类、静态内部类、局部内部类和匿名内部类。
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。
二、内部类的分析
-
内部类的位置
- 成员内部类:定义在外部类的内部,类似于成员方法,类和成员都不能使用static修饰
- 静态内部类:定义在外部类的内部,类似于静态方法,类使用static修饰,成员也可使用static修饰
- 局部内部类:定义在外部类的某一作用域内部(如静态代码块、代码块、静态方法、普通方法),类和成员都不能使用static修饰
- 匿名内部类:定义在外部类的任意位置(如静态变量、成员变量、静态代码块、代码块、静态方法、普通方法),类和成员都不能使用static修饰
-
内部类与外部类的依赖
- 成员内部类:依赖外部类,需要通过外部类对象来创建成员内部类的实例对象
- 静态内部类:不依赖外部类,可直接创建静态内部类的实例对象
- 局部内部类:与外部类无关,只能在该局部位置内创建局部内部类对象
- 匿名内部类:与外部类无关
-
内部类可以拥有的成员
- 成员内部类:可拥有非静态的成员,可使用任何修饰符修饰
- 静态内部类:可拥有任何的成员(静态、非静态),可使用任何修饰符修饰
- 局部内部类:可拥有非静态的成员,可使用任何修饰符修饰
- 匿名内部类:可拥有非静态的成员,可使用任何修饰符修饰
-
内部类访问外部类成员
- 成员内部类:可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
- 静态内部类:可以访问外部类静态的成员,可以是任何修饰符修饰的
- 局部内部类:
- 若定义在静态部分中,可以访问外部类静态的成员,可以是任何修饰符修饰的;
- 若定义在非静态部分中,可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
- 匿名内部类:
- 若定义在静态部分中,可以访问外部类静态的成员,可以是任何修饰符修饰的;
- 若定义在非静态部分中,可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
-
外部类访问内部类成员
- 成员内部类:外部类想要访问成员内部类的成员,需要先创建成员内部类实例对象,再通过实例对象去访问。
- 静态内部类:
- 外部类可访问静态内部类的静态成员,可以是任何修饰符修饰的;
- 外部类想要访问静态内部类的非静态成员,需要先创建静态内部类实例对象,再通过实例对象去访问。
- 局部内部类:外部类不可访问局部内部类成员
- 匿名内部类:外部类想要访问匿名内部类的成员,需要能拿到匿名内部类实例对象,再通过实例对象去访问(但也只能访问当匿名内部类的父类原有成员,若是匿名内部类自定义的成员则还是无法访问)。
-
内部类成员和外部类成员重名
内部类使用成员时,当外部类的成员和内部类的成员重名时,会发生隐藏现象(外部类的成员会被隐藏),默认情况下访问的是内部类的成员(就近原则),所以一般建议:
- 在内部类中访问自己的静态成员:<内部类>.<内部类中的成员名>
- 在内部类中访问自己的非静态成员:this.<内部类中的成员名>
- 在内部类中访问外部类的静态成员:<外部类类名>.<外部类中的成员名>
- 在内部类中访问外部类的非静态成员:<外部类类名>.this.<外部类中的成员名>
-
内部类和外部类的编译
外部类和内部类在编译后是两个不同的class文件。
- 成员内部类:内部类的class文件名称:外部类名$内部类名.class
- 静态内部类:内部类的class文件名称:外部类名$内部类名.class
- 局部内部类:内部类的class文件名称:外部类名$编号+内部类名.class
- 匿名内部类:内部类的class文件名称:外部类名$编号.class
三、内部类的分类
内部类可分为四种:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
1. 成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部。类似于成员方法,成员内部类不能拥有静态域但是可以访问外部类的静态部分。
- 定义在外部类的内部,类似于成员方法,类和成员都不能使用static修饰
- 依赖外部类,需要通过外部类对象来创建成员内部类的实例对象
- 可拥有非静态的成员,可使用任何修饰符修饰
- 可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
- 外部类想要访问成员内部类的成员,需要先创建成员内部类实例对象,再通过实例对象去访问
- 内部类使用成员时,当外部类的成员和内部类的成员重名时,会发生隐藏现象(外部类的成员会被隐藏),默认情况下访问的是内部类的成员(就近原则)
- 外部类和内部类在编译后是两个不同的class文件,内部类的class文件名称:外部类名$内部类名.class
public class OuterClass {private static String a = "outer static filed";private String b = "outer filed";public static String method1() {return "outer static method";}public String method2() {return "outer method";}class InnerClass {public void getOuter() {// 1.成员内部类访问外部类的静态变量System.out.println(OuterClass.a);// 2.成员内部类访问外部类的静态方法System.out.println(OuterClass.method1());// 3.成员内部类访问外部类的成员变量System.out.println(OuterClass.this.b);System.out.println(b);// 不建议使用这种方式// 4.成员内部类访问外部类的普通方法System.out.println(OuterClass.this.method2());System.out.println(method2());// 不建议使用这种方式}}
}
public static void main(String[] args) {// 方式1:OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();// 方式2:OuterClass outerClass = new OuterClass();InnerClass innerClass1 = outerClass.createInnerClass();}
创建成员内部类实例
格式:外部类名.内部类名 成员内部类对象名 = new 外部类名().new 内部类名()
2. 静态内部类
静态内部类也是定义在另一个类里面的类,使用static修饰,类似于静态方法,静态内部类不需要外部类对象产生就能使用,静态内部类只能访问外部类的静态部分,不能访问外部类的实例部分。
- 定义在外部类的内部,类似于静态方法,类使用static修饰,成员也可使用static修饰
- 不依赖外部类,可直接创建静态内部类的实例对象
- 可拥有任何的成员(静态、非静态),可使用任何修饰符修饰
- 可以访问外部类静态的成员,可以是任何修饰符修饰的
- 外部类可访问静态内部类的静态成员,可以是任何修饰符修饰的;
- 外部类想要访问静态内部类的非静态成员,需要先创建静态内部类实例对象,再通过实例对象去访问。
- 内部类使用成员时,当外部类的成员和内部类的成员重名时,会发生隐藏现象(外部类的成员会被隐藏),默认情况下访问的是内部类的成员(就近原则)
- 外部类和内部类在编译后是两个不同的class文件,内部类的class文件名称:外部类名$内部类名.class
public class OuterClass {private static String a = "outer static filed";private String b = "outer filed";public static String method1() {return "outer static method";}public String method2() {System.out.println(b);return "outer method";}static class InnerClass {private static String b = "inner filed";public String method2() {return "outer method";}public void getOuter() {System.out.println(a);}}
}
创建静态内部类实例
格式:外部类名.内部类名 成员内部类对象名 = new 外部类名.内部类名()
public class Test {public static void main(String[] args) {OuterClass.InnerClass innerClass = new OuterClass.InnerClass();}
}
3. 局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内,类似于局部变量。
- 定义在外部类的某一作用域内部(如静态代码块、代码块、静态方法、普通方法),类和成员都不能使用static修饰
- 局部内部类与外部类无关,只能在该局部位置内创建局部内部类对象
- 可拥有非静态的成员,可使用任何修饰符修饰
- 若定义在静态部分中,可以访问外部类静态的成员,可以是任何修饰符修饰的;
- 若定义在非静态部分中,可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
- 外部类不可访问局部内部类成员
- 内部类使用成员时,当外部类的成员和内部类的成员重名时,会发生隐藏现象(外部类的成员会被隐藏),默认情况下访问的是内部类的成员(就近原则)
- 外部类和内部类在编译后是两个不同的class文件,内部类的class文件名称:外部类名$编号+内部类名.class
public class OuterClass {private static String a = "outer static filed";private String b = "outer filed";static {class InnerClass1 {public void method2() {System.out.println(a);}}}{class InnerClass1 {public void method2() {System.out.println(a);System.out.println(b);}}}public static void method1() {class InnerClass1 {public void method2() {System.out.println(a);}}}public void method2() {class InnerClass1 {public void method2() {System.out.println(a);System.out.println(b);}}InnerClass1 innerClass1 = new InnerClass1();}
}
创建局部内部类实例
在局部内部类的作用域内通过new对象的方式创建对象。
格式:局部内部类名 局部内部类对象名 = 局部内部类名();
4. 匿名内部类
匿名内部类应该是我们编写代码时用得最多的,它满足了我们动态自定义代码的需求。
匿名内部类可以看作是特殊的局部内部类,其本质就是一个继承/实现了某个类(接口,普通类,抽象类)的子类匿名对象。
- 匿名内部类没有名称,没有构造函数,且使用者无法创建构造函数,但是实际上JDK为匿名内部类生成了构造函数
- 定义在外部类的任意位置(如静态变量、成员变量、静态代码块、代码块、静态方法、普通方法),类和成员都不能使用static修饰
- 匿名内部类与外部类无关
- 可拥有非静态的成员,可使用任何修饰符修饰
- 若定义在静态部分中,可以访问外部类静态的成员,可以是任何修饰符修饰的;
- 若定义在非静态部分中,可以访问外部类任何的成员(静态、非静态),可以是任何修饰符修饰的
- 外部类想要访问匿名内部类的成员,需要能拿到匿名内部类实例对象,再通过实例对象去访问(但也只能访问当匿名内部类的父类原有成员,若是匿名内部类自定义的成员则还是无法访问)。
- 外部类和内部类在编译后是两个不同的class文件,内部类的class文件名称:外部类名$编号.class
匿名内部类的定义
格式:new 接口名|类名(){重写方法}
如果重写方法为非必要的,原则上是可以没有重写方法部分的。
public class Test {public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {}};Runnable runnable1 = new Runnable() {@Overridepublic void run() {}};}
}
匿名内部类与Lambda表达式
从Java8开始,引入了Lambda表达式,将代码块作为参数使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。
Lambda表达式的代码块就是实现接口方法的方法体。
public class Test {public static void main(String[] args) {Runnable runnable = () -> {System.out.println("run.... ");};}
}
Lambda代码块写的是Runnable接口的run方法的方法体。
两者的不同之处:
- 使用匿名内部类方式定义的内部类:编译之后,会生成一个单独的class字节码文件(外部类名$编号.class);
- 使用Lambda表达式创建的内部类:编译之后,不会生成一个单独的class字节码文件,对应的字节码会在运行的时候动态生成。
相关文章:
Java内部类
文章目录一、内部类的概念二、内部类的分析三、内部类的分类1. 成员内部类2. 静态内部类3. 局部内部类4. 匿名内部类匿名内部类与Lambda表达式一、内部类的概念 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。内部类…...
Centos系统里运行java的jar包
目前使用springboot开发是嵌入方式的tomcat,不需要单独使用tomcat,那么经常在服务器上运行jar包,这里记录一下在centos7系统里运行jar的方式。在运行之前需要确定centos7系统是否安装了java环境以及配置环境变量,还有jar需要运行的…...
招标采购流程的电子招标采购,是管理复杂供应链和多层供应商的高效方式。
负载均衡(Load Balance) 由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其处理能力和计算强度也相应地增大,使得单一的服务器设备根本无法承担。在此情况下,如果扔掉现有设…...
【C语言】C程序结构和基本语法
1、C语言程序结构 我们学习一门编程语言,第一个实例都是"hello world!",下面看一个最简单的C程序结构。 #include <stdio.h>int main() {/* 我的第一个 C 程序 */printf("Hello, World! \n");return 0; }程序的第一行 #incl…...
YOLOv8 目标检测 | 自定义数据集
本文介绍了使用用于目标检测的自定义数据训练 YOLOv8 模型。我正在使用来自 kaggle 的 yolo 格式的“Face Mask Dataset”,数据集链接如下:https://www.kaggle.com/datasets/maalialharbi/face-mask-dataset?resourcedownloadYOLOv8 是目前最先进的 YOL…...
Lua语法入门
注意:文章将持续更新完善 文章目录一. 初识Lua二. HelloWorld三. Lua的数据类型四. 变量五. 循环六. 函数七. 条件控制一. 初识Lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中&#…...
华为OD机试真题JAVA实现【最小步骤数】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出说明示例二输入输出解题思路...
预检请求OPTIONS
这里写目录标题简单请求和非简单请求简单请求非简单请求预检请求OPTIONS简单请求和非简单请求 浏览器将请求分为两大类:简单请求(simple request)和非简单请求(not-so-simple request) 简单请求 简单请求࿰…...
引入短信服务发送手机验证码进行安全校验
其他方案>引入QQ邮箱发送验证码进行安全校验 相对短信验证码,操作更简单而且免费 最近想给自己的项目在注册时加点安全校验,准备使用免费的邮箱验证来着,在上一篇引入QQ邮箱进行安全校验时,看有朋友说阿里云会送一些短信服务免…...
opencv绘制直线
大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...
Seata源码学习(五)- Seata服务端(TC)源码解读
Seata源码分析- Seata服务端(TC)源码解读 上节课我们已经分析到了SQL语句最终的执行器,但是再往下分析之前,我们需要先来分析一下TM客户端与TC端通讯以后,TC端的具体操作 服务端表解释 我们的Seata服务端在应用的时…...
低版本jQuery导致XSS Nuclei FUZZ POC
目录 1.前言 2. Nuclei FUZZ jQuery XSS POC 3.漏洞验证 4.修复建议 1.前言 我记得以前用那些漏扫工具时时常会报一个低版本jQuery的安全问题,当时还不会验证。直到有一天,它托梦给我。我悟了。低版本jQuery导致XSS POC文件文末获取。...
【Linux】进程的描述组织与进程状态
文章目录🎪 进程的描述组织🚀1.什么是进程🚀2.进程的形成🚀3.进程标识符 *⭐3.1 PS命令查看PID⭐3.2 /proc目录查看进程属性🚀4.父子进程⭐4.1 系统调用获取PID⭐4.2 fork创建子进程⭐4.3 fork双返回值问题⭐4.4 写时拷…...
8.2.1.1 WHERE 子句优化
本节讨论可用于处理 WHERE 子句的优化。示例使用 SELECT 语句,但相同的优化适用于 DELETE 和 UPDATE 语句中的 WHERE 子句。 注意 因为 MySQL 优化器的工作正在进行,所以这里并没有记录 MySQL 执行的所有优化。 您可能会尝试重写查询以使算术运算更快&am…...
拆个微波炉,分析一下电路
微波炉是用2450MHz的超高频电磁波来加热食品,它能无损穿越塑料,陶瓷,不能穿越金属,碰到金属会反射,但穿过含水食物,食物内的分子会高速摩擦,产生热量,使食物变熟。在厨房电器中&…...
DM8:DMDSC共享存储集群搭建-共享存储绑定
DM8:DMDSC共享存储集群搭建-共享存储绑定环境介绍:1 发现共享磁盘2 对共享存储进行分区格式化2.1 格式化成功但不可用2.2 解决问题修改错误的分区格式3 配置/etc/rc.d/rc.local3.1 编辑文件(两个节点配置相同)3.2 使rc.local生效4 重启操作系…...
Spark OOM问题常见解决方式
文章目录Spark OOM问题常见解决方式1.map过程产生大量对象导致内存溢出2.数据不平衡导致内存溢出3.coalesce调用导致内存溢出4.shuffle后内存溢出5. standalone模式下资源分配不均匀导致内存溢出6.在RDD中,共用对象能够减少OOM的情况优化1.使用mapPartitions代替大部…...
【Calcite源码学习】ImmutableBitSet介绍
Calcite中实现了一个ImmutableBitSet类,用于保存bit集合。在很多优化规则和物化视图相关的类中都使用了ImmutableBitSet来保存group by字段或者聚合函数参数字段对应的index,例如: //MaterializedViewAggregateRule#compensateViewPartial()…...
RabbitMQ相关概念介绍
这篇文章主要介绍RabbitMQ中几个重要的概念,对于初学者来说,概念性的东西可能比较难以理解,但是对于理解和使用RabbitMQ却必不可少,初学阶段,现在脑海里留有印象,随着后续更加深入的学习,就会很…...
在jenkins容器内部使用docker
在jenkins容器内部使用docker 1.使用本地的docker 进入/var/run,找到docker.sock [rootnpy run]# ls auditd.pid containerd cryptsetup dmeventd-client docker.pid initramfs lvm netreport sepermit sudo tmpfiles.d user chro…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
