Effective Java笔记(24)静态成员类优于非静态成员类

《Effective Java》第24条:静态成员类优于非静态成员类 上面的测试代码之所以输出的是 { },就是因为当调用 s.clear() 的时候,实际上执行的是HashMap内部类 keySet 类中的 clear() 方法,所以会将调用外部类(HashMap类)中的clear() 方法,将HashMap中的值全部清空。首先,前面的文字已经说过,非静态成员类(内部类)的实例会永久关联外围类的实例,因此内部类可以直接访问外围实例的所有成员(包括私有成员)。静态成员类(也叫静态内部类)是最简单的一种嵌套类,它声明在一个类的内部,可以访问外围类的所有成员,包括私有成员。 阅读详情

        嵌套类( nested class )是指定义在另一个类的内部的类 。 嵌套类存在的目的应该只是为它的外围类(enclosing class )提供服务 。 如果嵌套类将来可能会用于其他的某个环境中,它就应该是顶层类( top-level class ) 。 嵌套类有四种: 静态成员类( static member class )、非静态成员类( nonstatic member class )、匿名类( anonymous class )和局部类( local class )。 除了第一种之外,其他三种都称为内部类( inner class ) 。 本条目将告诉你什么时候应该使用哪种嵌套类,以及这样做的原因 。

        静态成员类是最简单的一种嵌套类 。 最好把它看作是普通的类,只是碰巧被声明在另一个类的内部而己,它可以访问外围类的所有成员,包括那些声明为私有的成员 。 静态成员类是外围类的一个静态成员,与其他的静态成员 一样,也遵守同样的可访问性规则 。 如果它被声明为私有的,它就只能在外围类的内部才可以被访问,等等 。

        静态成员类的一种常见用法是作为公有的辅助类,只有与它的外部类一起使用才有意义 。 例如,以枚举为例,它描述了计算器支持的各种操作 。Operation 枚举应该是 Calculator 类的公有静态成员类,之后 Calculator 类的客户端就可以用诸如 Calculator.Operation.PLUS 和Calculator.Operation.MINUS 这样的名称来引用这些操作 。

        从语法上讲,静态成员类和非静态成员类之间唯一的区别是,静态成员类的声明中包含修饰符 static 。 尽管它们的语法非常相似,但是这两种嵌套类有很大的不同 。 非静态成员类的每个实例都隐含地与外围类的一个外围实例相关联 。 在非静态成员类的实例方法内部,可以调用外围实例上的方法,或者利用修饰过的 this ( qualified this )构造获得外围实例的引用。如果嵌套类的实例可以在它外围类的实例之外独立存在,这个嵌套类就必须是静态成员类:在没有外围实例的情况下,要想创建非静态成员类的实例是不可能的 。

        当非静态成员类的实例被创建的时候,它和外围实例之间的关联关系也随之被建立起来;而且,这种关联关系以后不能被修改 。 通常情况下,当在外围类的某个实例方法的内部调用非静态成员类的构造器时,这种关联关系被自动建立起来 。 使用表达式 enclosing ­Instance.new MemberClass(args)来手工建立这种关联关系也是有可能的,但是很少使用 。 正如你所预料的那样,这种关联关系需要消耗非静态成员类实例的空间,并且会增加构造的时间开销 。

        非静态成员类的一种常见用法是定义一个 Adapter , 它允许外部类的实例被看作是另一个不相关的类的实例 。 例如,Map 接口的实现往往使用非静态成员类来实现它们的集合视图( collection view)这些集合视图是由 Map 的 keySet、entrySet 和 values方法返回的 。 同样地,诸如 Set 和 List 这种集合接口的实现往往也使用非静态成员类来实现它们的迭代器( iterator):

public class MySet<E> extends AbstractSet<E> {
    @Override 
    public Iterator<E> iterator( {
        return new MyIterator();
    }
    private class MyIterator implements Iterator<E> {
        // .....
    }
}

        如果声明成员类不要求访问外围实例,就要始终把修饰符 static 放在它的声明中, 使它成为静态成员类,而不是非静态成员类 。 如果省略了 static 修饰符,则每个实例都将包含一个额外的指向外围对象的引用 。 如前所述,保存这份引用要消耗时间和空间,并且会导致外围实例在符合垃圾回收时却仍然得以保留 。 由此造成的内存泄漏可能是灾难性的 。 但是常常难以发现,因为这个引用是不可见的 。

        私有静态成员类的一种常见用法是代表外围类所代表的对象的组件 。以 Map 实例为例,它把键( key )和值( value )关联起来 。 许多 Map 实现的内部都有一个 Entry 对象,对应于 Map 中的每个键一值对 。 虽然每个 entry 都与一个 Map 关联,但是entry 上的方法( getKey 、getValue 和 setValue )并不需要访问该 Map 。因此,使用非静态成员类来表示 entry 是很浪费的:私有的静态成员类是最佳的选择 。 如果不小心漏掉了 entry 声明中的 static 修饰符,该 Map 仍然 可以工作,但是每个 entry 中将会包含一个指向该Map 的引用,这样就浪费了空间和时间 。

        如果相关的类是导出类的公有或受保护的成员, 毫无疑问,在静态和非静态、成员类之间做出正确的选择是非常重要的 。 在这种情况下,该成员类就是导出的 API 元素,在后续的发行版本中,如果不违反向后兼容性,就无法从非静态成员类变为静态成员类 。

        顾名思义,匿名类是没有名字的 。 它不是外围类的一个成员 。 它并不与其他的成员一起被声明,而是在使用的同时被声明和实例化 。 匿名类可以出现在代码中任何允许存在表达式的地方。 当且仅当匿名类出现在非静态的环境中时,它才有外围实例 。 但是即使它们出现在静态的环境中,也不可能拥有任何静态成员,而是拥有常数变量( constant variable ),常数变量是 final基本型,或者被初始化成常量表达式的字符串域 。

        匿名类的运用受到诸多的限制 。 除了在它们被声明的时候之外,是无法将它们实例化的 。 不能执行 instanceof 测试或者做任何需要命名类的其他事情 。 无法声明一个匿名类来实现多个接口,或者扩展一个类,并同时扩展类和实现接口 。 除了从超类型中继承得到之外,匿名类的客户端无法调用任何成员 。 由于匿名类出现在表达式中,它们必须保持简短,否则会影响程序的可读性 。

        在 Java 中增加lambda之前,匿名类是动态地创建小型函数对象( function object)和过程对象( process Object)的最佳方式,但是现在会优先选择 lambda。匿名类的另一种常见用法是在静态工厂方法的内部。

        局部类是四种嵌套类中使用最少的类 。 在任何“可以声明局部变量”的地方,都可以声明局部类,并且局部类也遵守同样的作用域规则 。 局部类与其他三种嵌套类中的每一种都有一些共同的属性。 与成员类一样,局部类有名字,可以被重复使用 。 与匿名类一样,只有当局部类是在非静态环境中定义的时候,才有外围实例,它们也不能包含静态成员 。 与匿名类一样,它们必须非常简短,以便不会影响可读性 。

        总而言之,共有四种不同的嵌套类,每一种都有自己的用途。 如果一个嵌套类需要在单个方法之外仍然是可见的,或者它太长了,不适合放在方法内部,就应该使用成员类 。 如果成员类的每个实例都需要一个指向其外围实例的引用,就要把成员类做成非静态的;否则 ,就做成静态的。 假设这个嵌套类属于一个方法的内部,如果你只需要在一个地方创建实例, 并且已经有了一个预置的类型可以说明这个类的特征,就要把它做成匿名类;否则,就做成局部类。

Keil5 安装与卸载全攻略:从零开始到完美避坑 本文提供了Keil5集成开发环境的完整安装与卸载指南。针对嵌入式开发新手,详细解析了安装前的关键准备、MDK核心与C51双环境的安装激活步骤、常见问题排查,并重点介绍了如何彻底卸载软件以避免残留问题,帮助用户从零开始搭建稳定高效的开发环境。 阅读详情

相关推荐

昇腾AI处理器Ascend C编程:从C/C++基础到高性能算子开发实战

异构计算是提升AI算力效率的核心技术,通过在CPU之外引入专用处理器(如GPU、NPU)协同工作,实现大规模并行计算。其原理在于将计算密集型任务卸载到专用硬件,利用其高并行架构加速处理。技术价值在于突破传统CPU的算力瓶颈,为深度学习训练与推理提供强大动力,广泛应用于模型部署、科学计算和高性能计算场景。本文聚焦昇腾AI处理器的原生编程语言Ascend C,它基于C/C++标准扩展,通过显式内存管理和任务并行模型,充分发挥达芬奇架构中Cube与Vector单元的性能。针对CANN算子开发,文章详解了从环境搭建

weixin_34411563的博客 366

第24项:静态成员类优于非静态成员类(Favor static member classes over nonstatic)

  嵌套类(nested class)是指在另一个类中定义的内部类。嵌套类应该只存在于为其外围类(enclosing class)提供服务。如果嵌套类在某些其他上下文中有用,那么它应该是顶层类(top-level class)。有四种嵌套类:静态成员类,非静态成员类,匿名类和局部类。除第一种之外的其他类型都被称为内部类。在该项中将告诉你何时使用哪种嵌套类及其原因。   静态成员类是最简单的嵌套类。...

Coloured_Glaze的博客 445

单晶塑性abaqus-umat自学

单晶塑性abaqus-umat 摘要1. 简介2. 单晶弹塑性本构模型回顾2.1运动学 本文以翻译黄永刚老师的umat文章为主,这个颜色的为个人的理解。 摘要 包含单晶塑性的abaqus用户材料子程序。本文回顾有限元形式的单晶弹塑性和黏弹塑性,包含小变形理论,以及严格的有限变形和有限旋转理论。单晶的非弹性变形由于晶体滑移,假定遵从Schmid准则。提出多种多样的分切应力与剪切变形的自硬化和潜硬化关系,并且包含在子程序内。 1. 简介   有限元程序ABAQUS已经广泛应用在固体的变形与应力分析。除了自身大量

Niklas4088的博客 1万+

Java 静态成员类优于非静态成员类

嵌套类分为四种:静态成员类、非静态成员类、匿名类以及局部类,除了第一种,其余三种称为内部类。 一、静态成员类 类被声明为静态类,必须为静态成员类 静态类,一定为静态成员类 静态成员类作为公有的辅助类,只有与它的外部类一起使用才有意义 声明方式: 静态类:public static class StaticClass{} 非静态类:public class ClassName 访问权限: 静态类只能访问类内部的静态成员 非静态类可以访问类中所有成员 静态和非静态的唯一区别,静态成员类的声明中包含修饰符 st

南淮北安的博客 1165

MATLAB安装配置libsvm(附MinGW64配置)

首先声明版本,本人PC系统Windows10 64bit,matlab安装的2016b,libsvm安装的version3.2.21.首先需要下载libsvm包:从林教授的网站上下载: http://www.csie.ntu.edu.tw/~cjlin/libsvm/2.将libsvm3.2.2解压到matlab/toolbox目录下:解压后:D:\matlab2016b\toolbox\libs...

github_35807147的博客 4万+

FCL碰撞检测库在Windows下的编译与配置(MinGW+CMake)

本文详细介绍了在Windows系统下使用MinGW和CMake编译配置FCL碰撞检测库的完整流程。内容涵盖MinGW-w64、CMake的安装与环境配置,关键依赖库Eigen和libccd的安装,以及FCL源码的编译、安装与实战测试。重点解析了CMake配置命令中的关键参数与常见错误解决方案,旨在帮助开发者高效完成FCL在Windows平台的部署,适用于机器人、游戏物理引擎等需要精确碰撞检测的开发场景。

sunny的博客 483

Effective Java学习笔记--第24章静态成员类优于非静态成员类

嵌套类总共分为四种:静态成员类、非静态成员类、匿名类和局部类。除了第一种以为其他的都属于内部类。如果一个嵌套类需要在单个方法之外仍然可见,就应该使用成员类。如果成员类的每一个实例都需要一个指向外围类实例的引用,就使用静态成员类,否则就使用非静态成员类。如果这个嵌套类属于一个方法内部,只需要在一个地方快速创建实例,而且已经可以有一个预制的架构那就使用匿名类,否则,就作为局部类。

weixin_50353846的博客 880

蓝牙EDR模式中GFSK调制如何过渡到DPSK调制

这两份文档片段揭示了蓝牙Modem设计中非常精深的部分。它的核心思想是:通过精心的脉冲形状设计和重叠,来保证幅度连续;通过在保护间隔内执行一套复杂的“相位平滑算法”(重复、斜率保持、寻找基准点、冻结),来保证相位连续。Figure 3-2 则是将这个思想用图形化的方式展现出来,说明了脉冲在时间轴上的对齐和叠加关系。这种设计确保了发射机能够严格符合蓝牙规范的要求,实现不同调制方式之间的平滑、无毛刺切换,从而保障了通信的可靠性和高效的频谱利用率。

m0_49540263的博客 283

Effective Java 3rd 条目24 静态成员类优于非静态

嵌套类(nested class)是一个定义在另外一个类内部的类。嵌套类应该仅仅是为了服务外部类而存在。如果内嵌类在其他某些情形下有用,那么他应该是一个顶层类。有四种嵌套类:静态成员类(static member class)、非静态成员类(nonstatic member class)、匿名类(anonymous class)和本地类(local class)。只有第一种是被认为是内部类。这个条...

tigershin的专栏 307

Day 01: 与Python的第一次亲密接触

环境搭建 、第一个程序 Hello, World!、以及Python之禅 (The Zen of Python) 的解读。

杨小扩的博客 220

毕设-MobileNetV4:给YOLOv8装上轻量化“引擎”——通用瓶颈与C2f融合的实战教程

本文介绍了一种将MobileNetV4与YOLOv8结合的目标检测模型轻量化方案。MobileNetV4通过通用瓶颈(UB)结构实现多任务适配,其核心改进包括动态卷积核、注意力机制和多路径特征聚合,显著提升特征提取能力。作者详细阐述了如何在YOLOv8框架中实现MobileNetV4的通用瓶颈模块,包括"膨胀-卷积-注意力-压缩"的流程设计,并构建完整的backbone网络。该方案通过融合MobileNetV4的轻量化优势与YOLOv8的高效检测架构,在移动设备上实现了精度与速度的良好平

FJN110的博客 505

【Effective Java】条22:静态成员类优于非静态成员类

嵌套类是指定义在其他类里面的类,其旨在为外围类提供服务。嵌套类有四种,分别为静态成员类、非静态成员类、匿名类和局部类,其中非静态成员类、匿名类和局部类又称为内部类。 静态成员类 静态成员类是最简单的嵌套类。静态成员类是外围类的静态成员,且和其他静态成员一样遵守相同的访问规则。注意静态成员类只能访问外围类的静态成员。使用方法如下Demo所示: public class StaticMe...

简单用心品质生活 583

把 ABAP 开发对象装进 XML 行李箱:SAPlink 安装、插件、升级与协作迁移全指南

SAPlink是一款用于在SAP NetWeaver系统间导入导出ABAP对象的工具,特别适合临时协作、系统孤岛等场景。它通过XML文件(Slinkee和Nugget两种格式)传输开发对象,支持插件扩展多种对象类型。安装时需注意版本兼容性、权限和激活流程,使用时要区分覆盖选项的风险。相比正式运输系统,SAPlink更适用于快速共享、原型交付等非生产场景,但需配合命名规范和协作策略确保可维护性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 155

《Effective Java》解读第24条:静态成员类优于非静态成员类

本文介绍了Java中四种嵌套类的特性及适用场景。静态成员类是最常用的形式,无需绑定外围实例,适合Builder模式等场景;非静态成员类(内部类)隐式持有外围实例引用,适合迭代器等需要访问外围实例成员的场景;匿名类用于一次性实现接口或抽象类,Java 8后可用Lambda替代;局部类则定义在方法内部,使用最少。建议优先使用静态成员类,除非需要访问外围实例才使用非静态成员类,以减少不必要的内存消耗。合理选择嵌套类类型有助于优化代码结构和性能。

Cosmoshhhyyy的博客 908

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25

Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25 本文主要介绍了类和接口相关的内容

weixin_44453385的博客 883

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【读书笔记】Effective Java(类和接口)

读书笔记-Effective Java(类和接口)

我的博客 392

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Effective Java 第三版 中文翻译

effective-java-third-edition 介绍 Effective Java 第三版全文翻译,纯属个人业余翻译,不合理的地方,望指正,感激不尽! 目录 推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象   本章涉及创建和销毁对象,包括何时以及如何创建它们,何时以及如何避免创建它们,如何确保它们被及时销毁,以及如何管理在销毁之前必须进行的清理操作。 第1项:考虑静态工...

Coloured_Glaze的博客 3861

《Effective Java》学习笔记15--25

本栏是博主根据如题教材进行Java进阶时所记的笔记,包括对原著的概括、理解,教材代码的报错和运行情况。十分建议看过原著遇到费解地方再来参考或与博主讨论。致敬作者Joshua Bloch和各路翻译者们,以及为我提供可参考博文的博主们。 复制粘贴改格式好累,这几篇全都给出git地址,大家自己download下来看好了。或者想直接在浏览器上看可以考虑用这个名叫OctoTree的插件。安装教程网上大把,...

欢迎访问 花落的速度 的博客 322

Effective Java 学习总结

Effective Java 作为 Java 四大名著之一,聚焦于 Java 语言习惯和高效的用法。EJ 告诉读者如何更好地构建代码,以便代码能够更好地工作;也便于其他人能够理解这些代码,便于修改和改善;程序也会因此变得更加令人愉快,更加优雅。全书共90条,接下来笔者将逐条进行总结。不应该使用常量接口。一个类在内部使用某些常量是实现细节,常量接口会把这样的实现细节泄露到该类的导出 API 中标记接口:不包含方法声明的接口,它只是指明一个类实现了某种属性的接口。

Alioth4J的博客 2255

学习effective java-22类和接口之优先考虑静态成员类

该知识点是自己从书籍中学习的笔记。 嵌套类就是在类中定义的类,嵌套类仅仅是为它的外部类服务的。如果还需要给其他外部的类服务的话,那么就需要将该嵌套类提升一个层次。目前有四种嵌套套:静态成员类,非静态成员类,匿名类,局部类。除第一种类外,其他都可以成为内部类。 静态成员类可以看作仅仅是外部类的一个静态成员,如果静态成员类被声明为private的,那么该类就只能够在外部类的内部中使用。静态成员类只

啦啦的专栏 848

Effective Java 读书笔记

读书笔记

white_while的博客 1648

【Effective Java】第4章 读书笔记

第4章 类和接口 15,使类和成员可访问性最小化 尽可能地使每个类或者成员不能被外界访问。 公有类的实例域绝不能是公有的。 包含公有可变域的类通常并不是线程安全的。 让类具有公有的静态 final 数组域,或者这种域的访问方法是错误的。 16,要在公有类中使用访问方法而非公有域 公有类永远都不要暴露可变的的域 17,使可变性最小化 不可变类是指实例不可以被修改的类 17.1 不可变类要遵循的五条原则: 不要提供任何可以修改对象状态的方法。 保证类不会被扩展。 声明所有的域都是 final 的。 声明所有的

qq_45050687的博客 1330

Effective Java 第三版读书笔记(类和接口)

第15条.使类和成员的可访问性最小化 对于成员有四种可访问级别: 1.私有的(private)----- 只有在声明该成员的顶层类内部才可以访问这个成员。 2.包级私有的(package-private)----- 声明该成员的包内部的任何类都可以访问这个成员,也是默认访问级别,接口成员除外,接口成员默认的访问级别是公有的。 3.受保护的(protected)----- 声明该成员的类...

qq_27707957的博客 340

Effective java

1

weixin_47843332的博客 329

《Effective Java》第25条:限制源文件为单个顶级类

原文P92:永远不要把多个顶级类或者接口放在一个源文件中。但是当再从 Dessert.java 源文件中定义 Utensil类 和 Dessert类,在idea中,程序就会编译出错,编译器会提醒你定义了多个Utensil 和Dessert类。正常情况下,在Utensil.java 源文件中定义 Utensil类 、在 Dessert.java 源文件中定义 Dessert类。Java允许我们在一个Java文件中,定义多个顶级类,并且可以正常编译和使用,但是这种方式是没有任何好处的,只会带来巨大的风险。

TD_FAlmK的博客 299

3分钟快速阅读-《Effective Java》(三)

21.用函数对象来表示策略 简而言之,就是使用接口来定义要实现的策略方法,然后具体的实现类来实现不同的接口从而实现不同的策略,这就是所谓的函数对象来表示策略 22.优先考虑静态成员类 1.嵌套类包括以下四种,除了静态成员类,其他的都可以被称为内部类 1.1 静态成员类:可以被外部访问的一种辅助类,访问的时候并不需要实例化外部类, 1.2 非静态成员内部类,这样的类是需要外部类实例化之后才...

逍遥云恋 570
上一篇: Effective Java笔记(23)类层次优于标签类
下一篇: Effective Java笔记(25)限制源文件为单个顶级类
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值