想成为更优秀,更高效程序员,请阅读此书。总计78个条目,每个对应一个规则。

第二章 创建和销毁对象

  一,考虑用静态工厂方法代替构造器

  二, 遇到多个构造器参数时要考虑用builder模式

      /**
    * 1.直接传参阅读性差,2.JavaBean多线程下存在安全问题,3.builder适用于大于5个参数并且参数是可选得情况 建造者(builder) 模式
    * @author fancy
    */
    public class Person implements Serializable {
      private String name;
      private String age;
      private String sex;
      private String country;
      private String edc;
      public Person(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
        this.country = builder.country;
        this.edc = builder.edc;
      }
      public static class Builder {
        private String name;
        private String age;
        private String sex;
        private String country;
        private String edc;
        public Builder setName(String name) {
          this.name = name;
          return this;
        }
        public Builder setAge(String age) {
          this.age = age;
          return this;
        }
        public Builder setSex(String sex) {
          this.sex = sex;
          return this;
        }
        public Builder setCountry(String country) {
          this.country = country;
          return this;
        }
        public Builder setEdc(String edc) {
          this.edc = edc;
          return this;
        }
        public Person build() {
          return new Person(this);
        }
      }
      public static void main(String[] args) {
         Person person = new Person.Builder().setAge("20").setName("fancy").build();
      }
    }

  三,用私有构造器或者枚举类型强化Singleton属性

  四,通过私有构造器强化不可实例化的能力

     工具类实例对它没任何意义,添加私有构造器是有必要的。

      public class StringUtil {

      private StringUtil () {}

    }

  五,避免创建不必要的对象

     能重用对象的时候不要创建新对象。

     优先使用基本类型,尽量避免自动装箱。

  六,消除过期的对象引用

     长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏。

     引用对象已经过期,清空引用=null。

  七,比用使用终结方法

     终结方法(finalizer)通常是不可以预测的,也是很危险的。终结方法的缺点在于不能保证会被及时地执行。

     final:java中的关键字,修饰符。

     A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。

     B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.

         1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。

         2)被声明final的方法只能使用,不能重载。

     finally:java的一种异常处理机制。

     finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭

数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。

     finalize:Java中的一个方法名。

     Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是

在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

第三章 对于所有对象都通用的方法

  Object是一个具体得类,设计它主要为了扩展。

  八,覆盖equals时请遵守通用约定

     类具有自己独特的“逻辑相等”概念,这个时候需要覆盖equals方法,

  九,覆盖equals时总要覆盖hashcode

     相等的(equals)的对象必须具有相等的hash code。不相等的两个对象,hash code有可能相等。

  十,始终要覆盖toString

     返回对象中所有值得关注得信息

  十一,谨慎地覆盖clone()方法

     除非拷贝数组,否则没必要覆盖

  十二,考虑实现Comparable接口

    类具有非常明显得内在排序关系,比如按照字母排序、按照数值排序,应该考虑使用这个接口。

第四章 类和接口

  十三, 使类和成员的可访问性最小化

     设计良好得模块会隐藏所有得实现细节

     尽可能降低可访问性。

  十四,在公有类中使用访问方法而非公有域

     公有类永远都不应该暴露可变得域。

  十五,使可变性最小化

     除非有很好的理由,坚决不要每个get方法编写set方法,尽量每个域都是final的。

  十六,复合优先于继承

     private final Set<E> s;// 增加一个私有的成员变量,继承违背了封装原则,子类父类存在子类型关系时才用继承。

     这样做等同于新建一个类,而这个类的全部作用就是给原来继承的父类的所有已知方法进行代理。

     代理方法是死的,不会随原父类方法的扩充而改变,他只是调用原父类的方法,所以,当原父类新增方法时这个代理的类是不知道也不会受到影响的。

     这样做也是有缺陷的:

     虽然这样不会因为父类的扩展和子类发生冲突,但同样的父类扩展的好处也不会被子类自动继承,这时需要手动去更新代理类,设想一下,在一个比较复杂的系统中,所

有继承关系都使用这种复合关系,那么任何非叶级的类增加方法都要在该类的复合类中增加代理方法,代码维护工作量会增加,而且父类增加方法时无法立即知道新方法与子类可能

存在的冲突,而导致了重复的工作。

     一般父类扩展方法与子类发生冲突是因为子类在扩展方法时没有从对象分类上进行充分的考虑导致在错误的分类范围定义错误的行为,是可以从设计上就避免的问题。

  十七,要么为继承而设计并提供文档说明,要么就禁止继承

  十八,接口优于抽象类

     抽象类允许包含某些方法的实现;接口不允许。

     为实现抽象类定义的类型,类必须成为抽象类的一个子类,Java只允许单继承;可以implement多个接口

  十九,接口只用于定义类型

     接口不应该用来定义常量。

  二十,类层次优于标签类、

     标签类:香蕉苹果放到一个标签类中,冗长

     类层次:水果父类,香蕉苹果分别继承

  二十一,用函数对象表示策略

     函数指针的主要用途就是实现策略(Strategy)模式。Java中声明一个接口表示策略,并且为每个具体策略声明一个实现了该接口的类。例:Arrays.sort(array, comparator);

  二十二,优先考虑静态成员类

     嵌套类有四种:静态成员类,非静态成员类,匿名类,局部类。

第五章 泛型

  二十三,不要在新代码中使用原生态类型

     原生态类型可能导致运行时异常,保留是为了兼容性

     泛型<E>,<Object>参数化类型,<?>无限制通配符类型

  二十四,消除非受检警告

     尽可能消除每一个非受检警告,运行时可能抛出ClassCastException。

     无法消除使用注释,@SuppressWarnings("unchecked")

  二十五,List优先于数组

     String类型放入int类型数组,运行时才会抛出异常

  二十六,优先考虑泛型

  二十七,优先考虑泛型方法

  二十八,利用有限制通配符来提升API的灵活性

  二十九,优先考虑类型安全的异构容器

第六章 枚举和注解

  三十,用enum代替int常量

     enum type:由一组固定的常量组成合法值的类型。

     功能强大,int数字翻译成字符串

  三十一,用实例域代替序数

     除了设计基于EnumSet,EnumMap外数据结构外基本用不到。

  三十二,用EnumSet代替位域

  三十三,用EnumMap代替序数索引

  三十四,用接口模拟可伸缩的枚举

  三十五,注解优先于命名模式

  三十六,坚持用Override注解

     覆盖父类方法上使用,编辑器可以替你防止大量错误。

  三十七,用标记接口定义类型

     标记接口(marker interface)是没有包含方法声明的接口。例:Serializable

第七章 方法

  三十八,检查参数有效性

     在方法体得开头处检查参数。比如对象是否为null。

  三十九,必要时进行保护性拷贝

    public Date getBrithday() {  

        return (Date) this.birthday.clone();  // 我造个新的实例扔给你,你随便折腾吧,影响不到我  ,防止使用者改变。

    } 

  四十,谨慎设计方法签名

     谨慎选择方法名、不要过于追求提供便利的方法、避免过长参数列表

  四十一,慎用重载

     尽量不要出现有两个相同参数的重载方法。

  四十二,慎用可变参数

  四十三,返回零长度的数组或者集合而不是null

     简化调用者非null判断工作

  四十四,为所有导出的API元素编写文档注释

第八章 通用程序设计

  四十五,将局部变量的作用域最小化

     第一次使用局部变量的地方声明

  四十六,for-each循环优先于传统的for循环

     简洁、预防bug、性能优势

     以下三种情况无法使用for-each:1.过滤,2.转换,3.平衡迭代

  四十七,了解和使用类库

     不要重新发明轮子

  四十八,如果需要精确的答案,请避免使用float和double

     如果数值范围不超过9位十进制用int

     如果数值范围不超过18位十进制用long

     如果数值范围超过18位十进制用BigDecimal

  四十九,基本类型优先于装箱类型

     基本类型更加简单,也更加快速。

  五十,如果其他类型更适合,则避免使用字符串

  五十一,当心字符串链接的性能

     认识String类

       1)String类是final类

       2)String类其实是通过char数组来保存字符串的。

       3)无论是sub操作、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。

     StringBuffer类的成员方法前面多了一个关键字:synchronized,在多线程访问时起到安全保护作用的

     StringBuilder不是线程安全的。

     String、StringBuilder、StringBuffer三者的执行效率:StringBuilder > StringBuffer > String

  五十二,优先使用接口而非类来引用对象

     List list = new ArrayList();

  五十三,接口优先于反射机制

     反射适用于部分对象实例化,不适合访问对象。

  五十四,谨慎地使用本地方法

     本地方法指本地程序设计语言(C,Python)来编写的特殊方法。

     必须使用需进行全面测试。

  五十五,谨慎地进行优化

     没有好的优化方法不要优化。

  五十六,遵守普遍接受的命名惯例

第九章 异常

  五十七,只针对异常的情况才使用异常

     不要用于普通的控制流。

  五十八,对可恢复的情况使用受检异常,对编程错误使用运行时异常

  五十九,避免不必要地使用受检的异常

  六十,优先使用标准的异常

     常用异常。

  六十一,抛出与抽象相对应的异常

  六十二,每个方法抛出的异常都要有文档

  六十三,在细节消息中包含能捕获失败的信息

  六十四,努力使失败保持原子性

     失败的方法调用应该使对象保持在被调用之前的状态

       1.设计不可变的对象,重新初始化常量

       2.操作之前检查有效性

       3.编写恢复代码

  六十五,不要忽略异常

第十章 并发

  六十六,同步访问共享的可变数据

     多个线程共享可变数据得时候,每个读或写操作得线程都必须是同步的。

  六十七,避免过度同步

     同步区域内做尽可能少的工作。避免性能降低和其他不确定性影响。

  六十八,executor和task优先于线程

     《Java并发编程实践》

  六十九,并发工具优先于wait和notify

     java.util.conconcurrent提供了更高级的语言,没有必要使用wait和notify。

  七十,线程安全性的文档化

     线程安全注解或说明。

  七十一,慎用延迟初始化

  七十二,不要依赖于线程调度器

  七十三,避免使用线程组

     过时了,可忽略。

第十一章 序列化

  定义:将一个对象编码成字节流,称作将该对象序列化(serializing),相反的过程称为反序列化(deserializing)

  好处:对象被序列化后,它的编码就可以从一台正在运行的虚拟机被传递到另一台虚拟机上,或者被储存到磁盘上,供反序列化使用。

  应用:序列化技术为远程通信提供了标准的小路级(wire-level)对象表示法,也为JavaBeans组件结构提供了标准的持久化格式。

  七十四,谨慎地实现Serializable接口

     为了继承而设计的类、用户接口,应该尽少实现Serializable接口.

     java.lang.throwable实现了Serializable接口,所以RMI的异常可以从服务器端传到客户端

     httpservlet实现了Serializable接口,会话状态(session state)可以被缓存。

  七十五,考虑使用自定义的序列化形式

  七十六,保护性地编写readObject方法

  七十七,对于实例控制,枚举类型优先于readResolve

  七十八,考虑用序列化代理代替序列化实例

《Effective Java 第二版》读书笔记的更多相关文章

  1. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  2. CSAPP 读书笔记 - 2.31练习题

    根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1)  属于第一种情况 sum = x ...

  3. CSAPP读书笔记--第八章 异常控制流

    第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...

  4. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  10. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. 一种斐波那契博弈(Fibonacci Nim)

    事实上我也不知道这算是哪个类型的博弈 是在复习$NOIP$初赛的时候看到的一个挺有趣的博弈 所以就写出来分享一下 $upd \ on \ 2018.10.12$忽然发现这个其实就是$Fibonacci ...

  2. nginx配置二级域名

    我在我的服务器上面跑了两个node应用程序,分别一个端口2368跑的是ghost博客,一个端口8000跑的是我的demo程序.想要一级域名zhangruojun.com用来访问博客,二级域名demo. ...

  3. Linux 安装 mysql 转 http://www.cnblogs.com/fnlingnzb-learner/p/5830622.html

    到mysql官网下载mysql编译好的二进制安装包,在下载页面Select Platform:选项选择linux-generic,然后把页面拉到底部,64位系统下载Linux - Generic (g ...

  4. css布局一屏幕的自适应高度

    css ;;list-style: none;} .top{height: 100px;background-color:orange;} .max{;background-color:skyblue ...

  5. cropper图片剪裁 , .toBlob()报错

    问题描述: 使用 cropper.js 剪裁图片时, 调用 toBlob() 方法报错 $("#image").cropper('getCroppedCanvas').toBlob ...

  6. Java中的RTTI

    RTTI可以帮助我们在运行时识别对象和类的信息. 一般传统的RTTI有三种实现方式: 1. 向上转型或向下转型(upcasting and downcasting),在java中,向下转型(父类转成子 ...

  7. vue-cli 组件运用

    // components ----- helloworld.vue <script> export default { name: 'Hellowworld', props: { //接 ...

  8. python sort、sorted

    1. (1).sorted()方法返回一个新列表(默认升序). list.sort() (2).另一个不同:list.sort()方法仅被定义在list中,sorted()方法对所有的可迭代序列都有效 ...

  9. S3 对象

    在 R 中,S3 对象系统是一个简单且宽松的面向对象系统.每个基本对象的类型都有一个 S3 类名称.例如:integer.numeric.character.logical.list 和 data.f ...

  10. 使用tk.mybatis快速开发curd

    使用mybatis已经是可以快速开发程序了,对于单表的curd似乎是一种可抽象的结果,下面介绍tk.mybatis的使用方式. maven引用 我使用的是这个版本,所以相关功能介绍也是这个版本. 使用 ...