Effective Java读书笔记(一):类、接口、对象

《Effective Java》学习心得——优雅而安全地构建Java对象 读了《Effective Java》这本书,感触良多。它刷新了我对Java语言的认识,纠正了原来的许多编程坏习惯。感叹Java的世界原来是如此丰富,内功对于一名技术人员是多么重要!本文记录本书的第2条建议——用构建器(Builder)优雅、安全地构建对象。 阅读详情

前言

“可能有人认为我不需要任何Java方面的书籍,但是我需要这本” - James Gosling

Java领域有几本被奉为圣经的书籍,其中(我认为)最著名的两本是《Thinking in Java》以及《Effective Java》。如果说Java编程思想教会我们Java这门语言,那么Effective Java则教会我们如何写出更好的Java语言程序。

这本书对于API开发程序员更为对口,但是对于普通的API用户同样有非常大的价值。此次读书笔记基本会摘抄书本原文,按照自己的顺序来组织书中的条目,而一些比较罕见的条目则会忽略。


类和接口

1. 使类和成员的可访问性最小化

尽可能地使每个类或者成员不被外界访问,使用与你正在编写的软件的对应功能相一致的、尽可能最小的访问级别。能private就别缺省,能缺省就别public,类能内部就别公开。
公有(public)类永远都不应该暴露可变的域,因为如果不改变API就无法改变它的数据表示法。如果需要访问域,可以通过提供访问方法,即getter/setter。有一种情况例外,即公有静态final(public static final)的域,这是一种常量形态。

2. 类层次的选择

复合(composition)优先于继承,只有当子类真正是父类的子类型,即子与父为”is-a”关系的时候,才应该使用继承,否则通常情况下,”子类”包含”父类”的一个实例,转发”父类”消息。
接口优先于抽象类,接口通常是定义允许多个实现类型的最佳选择,只有当演变的容易性比灵活性和功能更为重要的时候才应该使用抽象类。
类层次优先于标签类,”标签类”可以理解为冗长的switch-case/if-else语句,一般情况下可以使用Java的多态特性将其重构,也即策略模式。

3. 内部类

内部类有四种:静态成员类、非静态成员类、匿名类、局部类。

  • 静态成员类可视为普通的类,常见用法是作为辅助类,仅当与外部类一起使用时才有意义。
  • 非静态成员类的每个实例都隐含着与外围类的一个外围实例相关联,而这份引用可能会导致外围类在符合GC条件时由于被内部类引用着而无法GC。如果不需要外围实例,优先使用静态成员类。
  • 匿名类的常见用法是动态创建函数对象,实现策略。
  • 局部类与局部变量用法相仿,作用域规则也相同,一般也很少用…匿名类和局部类在非静态环境中定义时才有外围实例,并且不能包含静态成员。

构造器与对象

1. 多个构造器参数时使用Builder模式

Android开发者如果使用过Square的开源项目,对Builder模式必然不会陌生,通过链式调用最后build出一个目标对象。当大多数参数都是可选的时候使用Builder模式是比较优雅的方式,如果参数是必须时同样可以使用Builder模式,但需要做好说明工作。

2. 枚举实现Singleton属性

Singleton代表那些唯一的类对象。网上流传有多种单例的写法,有一篇著名的”单例的7种写法”~~,本书推荐的写法是使用静态成员,公有和私有都可以,私有则需要提供访问方法。

public class Singleton {
    public/private static final Singleton INSTANCE = new Singleton();
    private Singleton(){}
    ...
}

然而,如果涉及到序列化时,上面的方式需要额外的动作。比较好的实践方式是使用枚举。

public enum Singleton {
    INSTANCE;

    private int mFile;
    public void method();
}
3. 考虑用静态工厂代替构造器

这样做有几大优势:

  • 静态工厂有名称;
  • 可以做到不必每次调用它们的时候都创建一个新对象,比如上述的单例模式;
  • 可以返回子类对象;
  • 创建泛型类的实例可以使代码变得简单。

    public static <K,V> HashMap<K,V> newInstance() {
        return new HashMap<K,V>();
    }
4. 避免创建不必要的对象
  • 能只实例化一次某个对象,就尽量别多次实例化, 尤其在循环体中;
  • 注意自动装箱使基本类型装箱为对象,尤其在循环体中。
  • 池技术的使用,最经典的莫过于String,String str = "foo"与String str = new String("foo"),前者使用了常量池,后者则额外实例化了一个对象。
5. 消除过期的对象引用

这个话题和内存泄露息息相关,而内存泄露又是另外一个很大的话题,所以此处不讨论内存泄露。总而言之,如果一个对象已经无用,应该清空它的引用,即将这个对象的引用置为null。当程序员第一次被类似这样的问题困扰时,往往会过分小心:对于每一个对象引用,一旦不需要时就置为null,然而清空对象引用应该是一种例外而不是规范行为,消除过期引用最好的方法是让包含该引用的变量结束其生命周期。

6. 避免使用终结方法

需要清理资源时使用try-finally结构,在finally调用显式的清理方法,比如输入输出流的close方法等。终结方法是不可预测的,也是很危险的,应该避免使用终结方法。

7. 覆盖equals和hashCode方法

Object类这两个方法的覆盖很有讲究,但是IDE已经帮我们解决了。我们要知道的是:当类具有逻辑相等的概念时,即比较的是内容而非是否指向同一对象,就需要覆盖equals方法;在每个覆盖了equals方法的类中一般也需要覆盖hashCode方法,否则基于散列的集合可能出错。这两个方法更多讨论可以看之前一篇博文Java:equals和hashCode的理解

YOLO26优化:原创自研 | 自研独家创新DSAM注意力 ,基于BiLevelRoutingAttention注意力升级 提出新颖的注意力DSAM(Deformable Bi-level SpatialAttention Module),创新度极佳,适合科研创新,效果秒杀CBAM,Channel Attention+Spartial Attention升级为新颖的Deformable Bi-level Attention+Spartial Attention 阅读详情

相关推荐

SAP ABAP VL09 BAPI VL 216

ls_batch_item-fact_unit_denom = ls_lips_split-umvkn. "销售数量转换为 SKU 的值(分母)ls_batch_item-fact_unit_nom = ls_lips_split-umvkz. "销售数量转换成SKU的分子(因子)ls_batch_item-sales_unit_iso = ls_lips_split-meins. "被拆分DN基本单位。

ChampaignWolf的专栏 2297

effective java 34条 通过接口引用对象

List接口的2个实现ArrarList,VectorList sub1 =new ArrarList();//goodArrarList  sub2 = new ArrarList  ()//bad养成接口编程的习惯,会使程序有很高的灵活性,比如在List sub1 =new ArrarList()中,如果以后程序需要变化成Vector,可以直接写成List sub1 =new Vector()

soleghost的专栏 1095

DOSBOX 0.74模拟器安装Windows 95

DosBox本身带有5.0版的DOS系统,启动后虚拟一个Z盘存放有Dosbox特有的外部指令,如config.com、imgmount.com等,经测试,可以顺利安装各版本的windows 3.1系统,但是不能安装win95,需要用原版的dos镜像启动才能安装。1. 获取启动盘镜像文件 下载Win95启动软盘镜像文件,名为boot.img,放到DosBox 0.74的目录下。2. 制作硬盘镜像文件

xjnzhidao的博客 9306

基于JDK动态代理实现的接口链式调用(Fluent Interface)工具

什么是链式接口(Fluent Interface)根据wikipedia上的定义,Fluent interface是一种通过链式调用方法来完成方法的调用,其操作分为终结与中间操作两种。[1]下面是一个Wikipedia上的例子。Author author = AUTHOR.as("author"); create.selectFrom(author) .where(exists(sele

Revivedsun的专栏 2789

5分钟搞定PaddleOCR PP-OCRv5环境搭建:从安装到第一个识别Demo

本文提供了一份详细的PaddleOCR PP-OCRv5环境搭建与快速入门指南。通过清晰的步骤,指导读者在5分钟内完成从创建Python虚拟环境、安装PaddlePaddle框架和PaddleOCR库,到编写并运行第一个OCR识别Demo的全过程,帮助开发者快速体验最新的PP-OCRv5模型的文字识别能力。

sprite的博客 1266

Python量化交易实战:如何用vnpy+Tushare获取股票历史数据(附完整代码)

本文详细介绍了如何利用vn.py框架与Tushare数据接口,构建一个健壮的Python量化交易数据获取引擎。通过封装Tushare API,实现股票历史数据的自动化获取与格式转换,并适配vn.py的BarData结构,为策略回测与实盘交易提供稳定、高效的数据基础。文中提供了完整的代码实现,涵盖环境配置、核心封装逻辑及高级功能扩展。

cola5的博客 1218

Effective Java之通过接口引用对象(五十二)

List list= new ArrayList Map map = new HashMap 这样使用接口而不是类作为参数的类型 为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayL

heihei 461

Intel MKL库常用模块的C语言实现

文章目录1. 随机数生成1.1 等概率的01分布 viRngUniform1.2 (复)高斯分布 vsRngGaussian2. 向量-向量运算2.1 向量数乘与加法 cblas_caxpby2.2 向量内积 cblas_cdotu_sub2.3 向量范数 cblas_scnrm23. 矩阵-向量运算3.1 矩阵存储方案3.2 矩阵-向量乘法 cblas_cgemv4. 矩阵-矩阵运算4.1 矩阵...

月半 月半的博客 4649

Effective Java 读书笔记

Effective Java 读书笔记

SteveJrong's Blog 1165

大疆航线文件解析指南:5分钟搞懂KMZ里的template.kml和waylines.wpml区别

本文深入解析大疆无人机航线文件KMZ中template.kml与waylines.wpml的核心区别。template.kml是定义任务框架和全局参数的可编辑模板,而waylines.wpml是包含精确执行指令的最终文件。理解两者差异对于高效规划航线、批量生成任务及进行二次开发至关重要。

sun99的博客 864

试读源码在这里下载

试读文章的源码在这里下载。源码不做任何修改,重点重点重点:为了代码运行不报错,安装matlab 版本为 2021 及以上版本。matlab安装教程大家可以参考这个教程:手把手教你安装matlab软件。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 4301

《Effective Java》读书笔记

优先使用接口、泛型、静态工具类...

qq_43336396的博客 750

Oracle EBS R12.2.X JSP部署、编译和配置相关操作。

系统环境 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 背景 在某项目上,需要开发JSP相关程序,比如单点登陆、打印二维条码。当前把JSP部署编译以后,访问提示错误:Requested resource or page is not allowed in this site, 通过查SR发现Oracle EBS R12.2.X版本对客制化JSP进行权限控限,需要设置某些配置文件。 实例操作步骤 上传JSP文件 通常上传到$OA_HTML目录或其子目

陈显平的专栏-Oracle EBS 1910

福禄克红外热像仪屏幕不显示与图像异常排查指南

红外热像仪作为电气巡检、预防性维护和暖通检测的核心工具,其成像状态直接关乎设备诊断的准确性。当屏幕不显示或图像出现噪点、模糊、花屏等异常时,很多工程师会误判为硬件损坏而直接返厂,实则多数故障源于供电链路、排线接触或参数设置等基础环节。本文从热像仪的工作原理与典型故障分类出发,系统讲解从外在观察到内部排查的完整流程,涵盖电池交叉测试、屏幕排线检修、发射率与量程设置、非均匀校正等关键环节,并结合工程实践给出可操作的排除步骤与设备管理建议,帮助维护人员快速定位问题,降低维修成本。

weixin_34008784的博客 378

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Effective Java 笔记(三)

NO.7 在改写equals方法时请遵守通用约定 下列情况是不需要改写equals方法的: 1。同一个类的不同实例本质上是唯一的,就是个实例都有自己的本体(Identify)。 2。不关心该类是否提供了逻辑相等的功能。 3。父类已经改写过equals方法,对于子类来说,继承过来的equals方法已经是最合适的了。 4。一个类是私有的或者是包可见的,且确定它的equals方

264

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Effective Java读书笔记

第一章 引言 本文用来记录Effective Java学习过程中的各个知识点,受此时能力所限,有些点可能讲的不太清楚,或者理解有错误的地方,请多多指教! 第二章 创建和销毁对象 第一条 用静态工厂方法代替构造器 可参考文章:https://blog.youkuaiyun.com/u014129886/article/details/89670049 总而言之,静态工厂方法和共有构造器各有各的用处,我们需要理解他们各自的长处,静态工厂经常更加合适。 此处的静态工厂方法与设计模式中的工厂模式不同,这里是一种构造

逆水行舟,不进则退 1439

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

我的博客 392

《Effective Java》读书笔记(已更新至24条)

《Effective Java》读书笔记目录,这篇文章记录了我读这本书的一些想法和验证,带水印刘屠户的java养猪场是我的公众号,考虑后面的源码解析同步到公众号中。 1. 考虑用静态工厂方法代替构造器 第一条,考虑用静态工厂方法代替构造器 优点一:静态工厂可以很好的理解名称 四个构造方法,面对这样的构造方法,三个、四个是可以接受的,那如果是七个八个甚至是十几个呢?这个时候有一个好的...

Joseph_Geeker的博客 1469

《Effective Java》读书笔记三

一、明确接口的核心作用定义类型:接口的主要目的是为了定义一种特定的行为规范和类型标识。它描述了一组方法签名,任何实现该接口的类都必须提供这些方法的具体实现。通过接口,我们可以以一种统一的方式来处理不同的实现类,而无需关心具体的实现细节。类型标识的重要性:接口作为一种类型,可以在代码中用于变量声明、方法参数和返回值类型等。这使得代码更加灵活和可扩展,因为可以在运行时根据实际情况传入不同的实现类,而无需修改调用代码。二、避免不恰当的使用不要在接口中定义常量以外的变量:接口不应该被用作存储数据的地方。

qq_41831136的博客 801

《Effective Java 3rd》读书笔记——类和接口

使类和成员的可访问性最小化 区分一个组件设计得好不好,唯一重要的因素在于,它对于外部的其他组件而言,是否隐藏了其内部数据和其他实现细节。 尽可能地使每个类或成员不被外界访问。 对于顶层的(非嵌套的)类和接口,能做成包级私有的,就应该被做成包级私有(即不加任何修饰符)。这样就可以随心所欲的对其进行修改或删除。 如果一个包级私有的顶层类(或接口)只是在某一个类的内部被用到,那就应该考虑使它成为唯一使用...

日积月累,天道酬勤 630

【读书笔记】《Effective Java》(3)-- 类和接口

这一章的笔记时隔略久,因为开学了,有事情要做了。现在正值中秋佳节,放假了,有时间补完这篇笔记。 现在正在看下一章——泛型,发现难度更高一点,估计更新下一篇读书笔记的时间会更长。

lqadam的博客 1082

《Effective Java》读书笔记一

优先考虑依赖注入来引用资源可以使代码更加灵活、可测试和易于维护,是一种有效的设计实践。

qq_41831136的博客 772

【读书笔记】《Effective Java》第二章 第1条:创建和销毁对象

一、前言 《Effective Java》读书笔记系列 二、介绍 通常情况下客户端想要获取一个类A的实例,最传统的方式就是让A提供一个public的构造函数。实际上除此之外还有一种方式,那就是提供一个public的静态工厂方法 三、举例 以Integer为例子,Integer里面除了提供构造函数外,还提供了对应的静态工厂方法: public final class Integer extends Number implements Comparable<Integer> { //构造函数1

qq_38872414的博客 283

Effective Java读书笔记(1)—— 创建和销毁对象

很久以前买的一本《Effective Java》,最近开始读啦!从第二章开始看(第一章是引言),每一章都有若干条建议,翻了一下感觉对日常编码有很强的指导意义呀,勤劳的我决定写个读书笔记记录一下????。 第一条:考虑用静态工厂方法代替构造器 说到静态工厂方法,书里给的例子是包装类型,也就是平时常会用到的Integer.valueOf(),Integer.parseInt()想必也算,返回的都是Int...

Aviato 280

Effective Java读书笔记(2)—— 所有对象通用的方法

这一章写的是对所有对象都通用的一些方法,换言之就是Object带有的一些方法(Object类是所有类的父类),在这些方法中非final的类都是被设计为需要重写的,重写时需要遵从一些通用的约定。 第一条:使用try-with-resources语句代替try-finally语句 在进行IO操作和JDBC数据库操作的时候,最终都要手动调用close()关闭资源(用finalizer机制也可以,但是...

Aviato 301

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

使类和成员的可访问性最小化 在公有类中使用访问方法而非公有域 使可变性最小化 复合优先于继承 要么为继承而设计并提供文档说明要么禁止继承 接口优于抽象类 接口只用于定义类型 类层次优于标签类 用函数对象表示策略

albon arith 732
上一篇: Android:MVP模式
下一篇: Effective Java读书笔记(二):方法、通用程序设计
leelit
博客等级 码龄12年 63粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值