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…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
