Effective Java笔记(25)限制源文件为单个顶级类

        虽然 Java 编译器允许在一个源文件中定义多个顶级类,但这么做并没有什么好处,只会带来巨大的风险 。 因为在一个源文件中定义多个顶级类,可能导致给一个类提供多个定义 。 哪一个定义会被用到,取决于源文件被传给编译器的顺序 。

        为了更具体地说明,下面举个例子,这个源文件中只包含一个 Main 类,它将引用另外两个顶级类( Utensil 和 Dessert )的成员:

public class Main {public static void main(String[] args) {System.out.println(Utensil.NAME + Dessert.NAME);}
}

        现在假设你在一个名为 Utensil.java 的源文件中同时定义了 Utensil 和 Dessert :

class Utensil {static final String NAME = " pan";
}
class Dessert {static final String NAME = "cake";
}

当然,主程序会打印出“ pancake ” 。

现在假设你不小心在另 一 个名为 Dessert. java 的源文件中也定义了同样的两个类 :

class Utensil {static final String NAME = "pot" ;
}
class Dessert {static final String NAME = "pie";
}

        如果你侥幸是用命令 javac Main.java Dessert.java 来编译程序, 那么编译就会失败 , 此时编译器会提醒你定义了多个 Utensil和 Dessert 类 。 这是因为编译器会先编译Main.java ,当它看到Utensil 的引用(在 Dessert 引用之前),就会在 Utensil. java中查看这个类,结果找到 Utensil 和 Dessert 这两个类 。 当编译器在命令行遇到 Dessert.java 时,也会去查找该文件,结果会遇到 Utensil 和 Dessert 这两个定义 。

        如果用命令 javac Main.java 或者 javac Main.java Utensil.java 编译程序,结果将如同你还没有编写 Dessert.java 文件一样,输出 pancake 。 但如果是用命令 javac Dessert.java Main java 编译程序,就会输出 potpie 。 程序的行为受源文件被传给编译器的顺序影响,这显然是让人无法接受的 。

        这个问题的修正方法很简单,只要把顶级类(在本例中是指 Utensil 和 Dessert )分别放入独立的源文件即可 。 如果一定要把多个顶级类放进一个源文件中,就要考虑使用静态成员类,以此代替将这两个类分到独立源文件中去 。 如果这些类服从于另一个类,那么将它们做成静态成员类通常比较好,因为这样增强了代码的可读性,如果将这些类声明为私有的,还可以使它们减少被读取的概率 。 以下就是做成静态成员类的范例:

public class Test {public static void main(String[] args) {System.out.println(Utensil.NAME + Dessert . NAME);}private static class Utensil {static final String NAME = "pan";}private static class Dessert {static final String NAME = "cake";}
}

        结论显而易见 : 永远不要把多个顶级类或者接口放在一个源文件中 。 遵循这个规则可以确保编译时一个类不会有多个定义 。 这么做反过来也能确保编译产生的类文件,以及程序结果的行为,都不会受到源文件被传给编译器时的顺序的影响 。

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

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

相关文章

Linux系统中/boot和swap分区的作用

Linux系统中/boot和swap分区的作用 /boot和swap分区的作用为什么虚拟机不要swap /boot和swap分区的作用 /boot分区是Linux系统中的一个特定分区,它用于存放引导加载程序和内核镜像等启动所需的文件。当计算机启动时,BIOS或UEFI会加载/boot分区上的引导加…

【2023年电赛】运动目标控制与自动追踪系统(E 题)最简单实现

本方案的思路是最简单的不涉及复杂算法:识别矩形框,标记矩形框,输出坐标和中心点,计算长度,控制舵机移动固定长度!仅供完成基础功能参考,不喜勿喷! # 实现运动目标控制与自动追踪系…

租赁类小程序定制开发|租赁管理系统源码|免押租赁系统开发

随着互联网的发展,小程序成为了一种重要的移动应用开发方式。租赁小程序作为其中的一种类型,可以为很多行业提供便利和创新。下面我们将介绍一些适合开发租赁小程序的行业。   房屋租赁行业:租房小程序可以帮助房东和租户快速找到合适的租赁…

D中国粉尘过滤器行业竞争战略规划与投资前景策略研究报告2023-2029年

D中国粉尘过滤器行业竞争战略规划与投资前景策略研究报告2023-2029年 ################################### 《报告编号》: BG460706 《出版时间》: 2023年8月 《出版机构》: 中智正业研究院 《交付方式》: EMIL电子版或特快专递 免费售后 服务一年,具体内容及…

Vue2 第十七节 Vue中的Ajax

1.Vue脚手架配置代理 2.vue-resource 一.Vue脚手架配置代理 1.1 使用Ajax库 -- axios ① 安装 : npm i axios ② 引入: import axios from axios ③ 使用示例 1.2 解决开发环境Ajax跨域问题 跨域:违背了同源策略,同源策略规定协议名&#xff0…

idea-常用插件汇总

idea-常用插件汇总 码云插件 这个插件是码云提供的ps-码云是国内的一款类似github的代码托管工具。 Lombok Lombok是一个通用Java类库,能自动插入编辑器并构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或setter等方法…

Java源码规则引擎:jvs-rules 8月新增功能介绍

JVS-rules是JAVA语言下开发的规则引擎,是jvs企业级数字化解决方案中的重要配置化工具,核心解决业务判断的配置化,常见的使用场景:金融信贷风控判断、商品优惠折扣计算、对员工考核评分等各种变化的规则判断情景。 8月是收获的季节…

7种有效安全的网页抓取方法,如何避免被禁止?

网页抓取是一种从互联网上抓取网页内容的过程,但在网络抓取种相信您也经常遇到障碍?尤其是做跨境业务的,在抓取国外的网站时更有难度。但我们站在您的立场上,提供七种有效的方法来进行网页抓取而不被阻止,最大限度地降…

js调用栈分析

s调用栈 执行上下文:执行上下文就是当前js代码被解析和执行所在环境的抽象的概念(执行环境) js中的任何代码都是在执行上下文中执行的 js的执行环境:JS代码运行起来,执行上下文 js的执行上下文分为三种&#xff1a…

windows安装kafka配置SASL-PLAIN安全认证

目录 1.Windows安装zookeeper: 1.1下载zookeeper 1.2 解压之后如图二 1.3创建日志文件 1.4复制 “zoo_sample.cfg” 文件 1.5更改 “zoo.cfg” 配置 1.6新建zk_server_jaas.conf 1.7修改zkEnv.cmd 1.8导入相关jar 1.9以上配置就配好啦,接下来启…

Atcoder 做题记录

My OI Blog A R C 155 F \mathbb{ARC \ 155 \ F} ARC 155 F E, F 先咕着,做一些多项式题,这篇题解是我人工翻译的 [1] Double Counting 双重计数 考虑从叶子节点开始,用唯一的方式(如果有的话)来构造出一棵满足条件的树…

“AI乳腺癌检测”风暴眼中的三篇论文

深度学习和医学研究界对谷歌、纽约大学和DeepHealth发表的三篇有前途的乳腺癌诊断论文引发的讨论非常热烈。 几年前,纽约大学的一组研究人员开始发表关于将深度学习应用于癌症筛查的论文。该团队的最新论文《深度神经网络改善放射科医生在癌症筛查中的表现》于2019…

mybatisplus集成geometry实现增改功能

前言 在我们工作中想要实现将空间点位信息存储到数据库时,一般使用以下语句实现 INSERT INTO test-point ( point,text ) VALUES ( st_GeomFromText ( POINT(1 1) ),第1个点);update test-point set pointst_PointFromText(POINT(5 5)) where id 10;但是这样每次都要去编写新…

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio快速构建React完成点餐H5页面还原

文章目录 一、前言二、Cloud Studio 功能介绍三、实验介绍四、实操指导打开官网注册 Cloud Studio 五、开发一个简版的点餐系统安装 antd-mobile安装 Less 六、发布仓库七、开发空间八、总结 一、前言 IDE(集成开发环境)是一种软件工具,旨在…

Mybatis引出的一系列问题-动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底…

IDEA Go语言开发环境无法debug调试

现象描述 使用idea 搭建go开发环境后如果debug调试可能会遇到错误: could not launch process: decoding dwarf section info at offset 0x0: too short。 解决方法 有些回答go get -u github.com/derekparker/delve/cmd/dlv 。现在如果使用go mod方式的话这个是…

c++转换构造,拷贝构造,operator=

c转换构造,拷贝构造,operator 一.转换构造 定义一个类 class CTest { public:int m_a;CTest(int m_a):m_a(0){} };在主函数中定义对象 CTest tes1(1); CTest tes2 5;//我们发现这种定义对象的方式不符合常理,这里其实是发生了隐式类型转…

【Android】Retrofit2和RxJava2新手快速上手

写这篇博客的目的 网上关于Retrofit2和RxJava2的博客特别多,但是内容特别复杂,一上来就讲解很高级的用法 其实我们没必要像高考做题家一样,把每个API都背的滚瓜烂熟 熟悉基本用法,高阶用法需要的时候再逐个了解就行了 因为博客…

R语言linkET包绘制相关性组合网络热图

热图就是使用颜色来表示数据相关性的图。能绘制热图的R包很多,既往我们已经介绍了《R语言pheatmap包绘制热图》,今天咱们来介绍一下R语言linkET包绘制相关性组合网络热图。相关性热图的意思热图和其他数据的关联性,比较的是多数据间的内在关系…

【宝藏系列】Linux 常用磁盘管理命令详解

【宝藏系列】Linux 常用磁盘管理命令详解 文章目录 【宝藏系列】Linux 常用磁盘管理命令详解前言1️⃣ df2️⃣du3️⃣fdisk📟磁盘格式化📠磁盘检验⌨️磁盘挂载与卸除📀卸载/dev/hdc6 前言 Linux磁盘管理常用三个命令为df、du和fdisk。 df…