Java常见错误-内部类-简要分析

Java常见错误-内部类-简要分析

  • 概念
  • 分类
    • 成员内部类(非静态内部类)
    • 静态内部类
      • 成员内部类和静态内部类区别
    • 局部内部类
    • 匿名内部类
  • 注意事项
  • 总结

概念

内部类,顾名思义,就是在一个类的内部定义的类。这种设计允许将一个类的实现细节封装起来,并可以实现非常紧密的耦合,对于某些特定场景下,比如事件监听器模型、线程创建等,内部类能提供更加优雅和简洁的解决方案

分类

  1. 成员内部类(非静态内部类):这是最普通的内部类形式,它作为外部类的一个成员存在,可以直接访问外部类的成员变量和方法,即使它们是私有的。

  2. 静态内部类(静态嵌套类):静态内部类与成员内部类的主要区别在于静态内部类不需要依赖于外部类的实例,它可以通过外部类直接访问,类似于外部类中的静态成员。

  3. 局部内部类:局部内部类是在方法或代码块中定义的类,它的作用域仅限于该方法或代码块。它可以访问外部类的成员,同时也可以访问所在方法的局部变量,但要求这些局部变量必须被声明为final。

  4. 匿名内部类:没有名字的内部类,通常用来创建某个接口的实例或者实现抽象类的一个子类。它可以直接在需要使用的地方创建并实例化,常用于事件处理、线程创建等场景。

成员内部类(非静态内部类)

public class memberOuterClass {private int data = 5;class InnerClass {void display() {System.out.println("Data from outer class: " + data);}}public static void main(String[] args) {OuterClass outer = new OuterClass();OuterClass.InnerClass inner = outer.new InnerClass();inner.display();}
}

反编译.class:

public class memberOuterClass {private int data = 5;public memberOuterClass() {}public static void main(String[] var0) {memberOuterClass var1 = new memberOuterClass();InnerClass var2 = var1.new InnerClass();var2.display();}class InnerClass {InnerClass() {}void display() {System.out.println("Data from outer class: " + memberOuterClass.this.data);}}
}

​ 可以发现反编译后的代码中,外部类和内部类都多了一个无参的构造方法无论外部类还是内部类,编译器自动添加默认无参构造函数是为了确保类的可实例化性、支持继承机制以及维护类实例与其环境的正确关联

静态内部类

  • 静态内部类内允许有static属性、方法;
public class OuterClass {private static int staticData = 10;static class StaticInnerClass {void display() {System.out.println("Static data from outer class: " + staticData);}}public static void main(String[] args) {OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();inner.display();}
}

成员内部类和静态内部类区别

1、在是否可以使用static修饰上

  • 成员内部类内不允许有static属性、static方法;除非final static存常量池中

2、对外部类的引用及互相访问上

  • 非静态成员内部类:可以直接访问外部类的所有成员(包括静态和非静态),因为它持有一个隐式的外部类实例的引用(通常称为this$0)。这意味着非静态内部类的实例化必须在外部类的实例上下文中进行
  • ``静态成员内部类`不持有对外部类实例的直接引用,因此它不能直接访问外部类的非静态成员变量和方法 。它可以访问外部类的静态成员(包括静态字段和方法),因为静态成员属于类本身,不依赖于类的实例进行创建

3、内部类创建上

  • 静态内部类
public class Outer {public static class StaticInner {public void show() {System.out.println("静态内部类");}}
}// 使用静态内部类,无需创建Outer实例
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();
  • 成员内部类
public class Outer {public class MemberInner {public void show() {System.out.println("成员内部类");}}
}// 使用成员内部类,需先创建Outer实例
Outer outer = new Outer();
Outer.MemberInner inner = outer.new MemberInner();
inner.show();

小结静态内部类的实例化不需要外部类的实例。成员内部类的实例化需要先有外部类的实例,并通过外部类实例来创建内部类实例

4、一个外部类内多个成员内部类分别继承不同父类,实现"多继承"

public class Outer {// 第一个内部类继承自类Apublic class InnerA extends A {// InnerA 的实现}// 第二个内部类继承自类Bpublic class InnerB extends B {// InnerB 的实现}public static void main(String[] args) {// 创建 InnerA 和 InnerB 的实例InnerA innerA = new Outer().new InnerA();InnerB innerB = new Outer().new InnerB();}
}

局部内部类

public class OuterClass {void someMethod() {final int localData = 7;class LocalInnerClass {void show() {System.out.println("Local data: " + localData);}}LocalInnerClass local = new LocalInnerClass();local.show();}public static void main(String[] args) {OuterClass outer = new OuterClass();outer.someMethod();}
}

注:局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

匿名内部类

import java.util.ArrayList;
import java.util.List;public class Test {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("Hello");list.add("World");list.forEach(new java.util.function.Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});// 或者使用Lambda表达式简化(也是匿名内部类的一种体现)list.forEach(s -> System.out.println(s));}
}

匿名内部类是一种特殊的类,它不具备明确的构造器,这限制了它的应用场景。主要用途是作为接口的简短实现,尤其是用作回调机制。在编译时,它会被系统自动生成一个类似于Outer$1.class的名称。通常,匿名内部类用于扩展已有类或实现接口,并专注于提供必要的方法实现,而不涉及额外的功能

注意事项

//TODO

总结

​ 内部类是Java语言提供的一种特殊类,它允许类定义嵌套在其他类中,这为程序设计提供了更大的灵活性。不同类型的内部类有着不同的应用场景和访问规则,如成员内部类用于需要访问外部类非静态成员的情况,静态内部类更像一个独立的类但逻辑上属于外部类,局部内部类和匿名内部类则常用于临时性需求,如事件处理或实现特定接口的简短实现。理解并恰当使用内部类,可以使代码更加清晰、高效和易于维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/24535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习-10-测试

深度学习-10-测试 本文是《深度学习入门2-自製框架》 的学习笔记&#xff0c;记录自己学习心得&#xff0c;以及对重点知识的理解。如果内容对你有帮助&#xff0c;请支持正版&#xff0c;去购买正版书籍&#xff0c;支持正版书籍不仅是尊重作者的辛勤劳动&#xff0c;也是鼓励…

Web前端ES6-ES13笔记合集(下)

#### 五.ES10新特性 ##### 1. Object.fromEntries > Object.fromEntries()方法允许你轻松地将键值对列表转换为对象 js const arr [["name", "kerwin"], ["age", 100]]; console.log(Object.fromEntries(arr))//{name: kerwin, age: 100} …

pytorch 笔记:pytorch 优化内容(更新中)

1 Tensor创建类 1.1 直接创建Tensor&#xff0c;而不是从Python或Numpy中转换 不要使用原生Python或NumPy创建数据&#xff0c;然后将其转换为torch.Tensor直接用torch.Tensor创建或者直接&#xff1a;torch.empty(), torch.zeros(), torch.full(), torch.ones(), torch.…

树莓派【Raspberry Pi-64位】3b+,Pi4J 2.0入门

一.前言: 前面的文章讲解了树莓派在centos7 arm64版本下的使用,用一款智能小车为例子,做了代码实践。 由于centos7不再维护,且Pi4J 1.x版本也因为WiringPi 的局限,Pi4J从1.x升级为2.x.所以本专栏的技术栈也将进行调整,A.从centos7系统回到Raspberry Pi-64位系统。B.Pi4…

4.通用编程概念

目录 一、变量与常量1.1 变量1.2 常量 二、遮蔽三、数据类型3.1 标量类型1. 整型2. 浮点型3. 布尔类型4.字符类型 3.2 复合类型1. 元组2. 数组 四、函数五、语句和表达式六、函数的返回值 一、变量与常量 1.1 变量 在Rust中默认的变量是不可变的&#xff0c;如果修改其值会导致…

《青少年编程与数学》课程方案:4、课程策略

《青少年编程与数学》课程方案&#xff1a;4、课程策略 一、工程师思维二、使命感驱动三、价值观引领四、学习现代化五、工作生活化六、与时代共进 《青少年编程与数学》课程策略强调采用工程师思维&#xff0c;避免重复造轮子&#xff0c;培养使命感&#xff0c;通过探索兴趣、…

编程语言有哪些?这些希望你都知道

编程语言有哪些 编程语言有很多种&#xff0c;包括但不限于以下几种&#xff1a; Java&#xff1a;当今最普遍使用的开发语言之一&#xff0c;简单易学&#xff0c;且跨平台性非常强&#xff0c;对网络开发的支持令人称赞。Python&#xff1a;语法清楚&#xff0c;干净&#…

【Vue】如何提供访问vuex的数据

文章目录 一、提供数据二、访问Vuex中的数据通过$store访问的语法1&#xff09;模板中使用2&#xff09;组件逻辑中使用3&#xff09;js文件中使用 三、通过辅助函数 - mapState获取 state中的数据 一、提供数据 State提供唯一的公共数据源&#xff0c;所有共享的数据都要统一…

[office] 快速删除excel中的空行和列的方法 #其他#学习方法#经验分享

快速删除excel中的空行和列的方法 用户在网上下载好的Excel表格打开之后发现有很多空白行&#xff0c;怎么样将这些空白行或单元格一次性删除掉呢?下面教大家在Excel中用定位一次性可以把空白行删除 用户在网上下载好的Excel表格打开之后发现有很多空白行&#xff0c;怎么样将…

Vue3 使用audio播放语音+监听播放语音完成事件

需求&#xff1a;输入一段文字&#xff0c;点击语音框&#xff0c;将本地语音&#xff08;提前准备好的&#xff09; 播放出来 播放中效果 代码 <div class"listConAI" click"handleOpenSpeech" ><imgsrc"../../../../assets/images/blueo…

web前端 孙俏:深度探索与实战之路

web前端 孙俏&#xff1a;深度探索与实战之路 在这个数字化、信息化的时代&#xff0c;web前端技术以其独特的魅力&#xff0c;吸引着越来越多的开发者投身其中。今天&#xff0c;我们将跟随孙俏的脚步&#xff0c;一同探索web前端的深度与广度&#xff0c;揭开其神秘的面纱。…

中文文案写作有哪些合适的AIGC工具?

这是计育韬老师第 8 次开展面向全国高校的新媒体技术公益巡讲活动了。而在每场讲座尾声&#xff0c;互动答疑环节往往反映了高校师生当前最普遍的运营困境&#xff0c;特此计老师在现场即兴答疑之外&#xff0c;会尽量选择有较高价值的提问进行文字答疑梳理。 *本轮巡讲主题除了…

【Vue】开启严格模式及Vuex的单项数据流

文章目录 一、引出问题二、开启严格模式 一、引出问题 目标 明确 vuex 同样遵循单向数据流&#xff0c;组件中不能直接修改仓库的数据 这样数据的流向才会更加清晰&#xff0c;将来对数据的修改&#xff0c;都在仓库内部实现的&#xff0c;更易于维护 直接在组件中修改Vuex中…

Git:版本控制的艺术与GitLab实战指南

在当今快速发展的软件开发领域&#xff0c;高效、协同的代码管理是项目成功的关键。Git&#xff0c;作为一款分布式版本控制系统&#xff0c;凭借其强大的功能和灵活性&#xff0c;成为了众多开发者首选的版本控制工具。本文将带您深入探索Git的核心概念、基础操作&#xff0c;…

B3870 [GESP202309 四级] 变长编码

[GESP202309 四级] 变长编码 题目描述 小明刚刚学习了三种整数编码方式&#xff1a;原码、反码、补码&#xff0c;并了解到计算机存储整数通常使用补码。但他总是觉得&#xff0c;生活中很少用到 2 31 − 1 2^{31}-1 231−1 这么大的数&#xff0c;生活中常用的 0 ∼ 100 0…

Spring进阶技巧:利用AOP提前介入的巧妙实践

Spring框架中的面向切面编程&#xff08;AOP&#xff09;是一种强大的机制&#xff0c;它允许开发者在不修改原有代码的情况下&#xff0c;对程序进行横向切面的功能扩展。AOP提供了一种方式&#xff0c;可以在目标Bean的生命周期早期阶段就实施切面逻辑&#xff0c;这为我们在…

Python 中如何使用 lambda 函数

在 Python 中&#xff0c;可以使用 lambda 函数来创建匿名函数。lambda 函数的语法是&#xff1a;lambda 参数: 表达式。以下是一些使用 lambda 函数的例子&#xff1a; 通过 lambda 函数来计算两个数的和&#xff1a; add lambda x, y: x y print(add(2, 3)) # 输出 5通过…

Oracle 日志挖掘

oracle 11g 日志挖掘测试 需要开启补充日志 alter database add supplemental log data; SELECT SUPPLEMENTAL_LOG_DATA_MIN, SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;在用户下执行一些删除&#xff0c;插入等操作 SQL> create table zxy( …

LLM评测数据集

1. C-Eval 数据集源地址: C-Eval Official Repository 数据范围: 该数据集包括学科类知识测试&#xff0c;涵盖广泛的学科知识&#xff0c;例如数学、物理、化学等。 数据集大小及数据形式: 数据集包含13,948道单选题&#xff0c;题目均为中文。 论文地址: C-Eval: A Multi-…

【一百一十】【算法分析与设计】[SDOI2009] HH的项链,树状数组应用,查询区间的种类数,树状数组查询区间种类数

P1972 [SDOI2009] HH的项链 [SDOI2009] HH的项链 题目描述 HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运&#xff0c;所以每次散步完后&#xff0c;他都会随意取出一段贝壳&#xff0c;思考它们所表达的含义。HH 不断地收集新的贝壳&#xff0c;因此&am…