《Effetive Java(中文版,第二版)》读后笔记

 

第一章 引言

1.Java语言支持四种类型:接口/类/数组和基本类型。前三种通常被称为引用类型。

2.类的成员由它的域。方法。成员类和成员接口组成。方法的签名由它的名称和所有参数类型组成,签名不包括它的返回类型。

第二章 创建和销毁对象

1.第1条:考虑用静态工厂方法代替构造器

    优势:(1)有名称

              (2)不必每次调用都创建一个新对象

              (3)可以返回原返回类型的任何子类型的对象

              (4)在创建参数化类型实例的时候,使代码更简洁

    缺点:(1)类如果不含公有的或者受保护的构造器,就不能被子类化

              (2)与其他静态方法实际上没有任何区别

2.服务提供者框架:多个服务提供者实现了一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。

    该框架的三个重要组件:(1)服务接口,提供者实现的;

                                         (2)提供者注册API,这是系统用来注册实现,让客户端访问它们的;

                                         (3)服务访问API,客户端用来获取服务的实例的。

                                         (4)服务提供者接口,这些提供者负责创建其服务实现的实例。(可选)

3.第2条:遇到多个构造器参数时要考虑用构建器

        重叠构造器模式

        JavaBeans模式

        Builder模式

4.第3条:用私有构造器或者枚举类型强化Singleton属性

//单例模式实现序列化需要添加ReadResolve方法
public class Singleton implements Serializable{
    private volatile static Singleton singleton;
    private Singleton (){}
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
 
    private Object readResolve() {
        return singleton;
    }
}
<span style="color:#000000">public enum Elvis{
   INSTANCE;
   public void leaveTheBuilding(){...}
}</span>

 

注:这种方法在功能上与公有域方法相近,但是它更加简洁,无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。虽然还未广泛采用,但单元素的枚举类型已经成为实现Singleton的最佳方法。

 第四章 类和接口

1.第15条:使可变性最小化

使类成为不可变,遵循以下五条规则:

(1)不要提供任何会修改对象状态的方法;

(2)保证类不会被扩展;

(3)使所有的域都是final的;

(4)使所有的域都成为私有的;

(5)确保对任何可变组件的互斥访问。

 

//确保类不可变性,类不允许自身被子类化。两种方法:
//1.使类成为final的
//2.让类的所有构造器都变成私有的或者包级私有的,并添加共有的静态工厂来代替公有构造器。
public class Complex{
    private final double re;
    private final double im;
private Complex(double re,double im){
    this.re = re;
    this.im = im;
}

    public static Complex valueOf(double re,double im){
        return new Complex(re,im);
    }
}

2.第16条:复合优先于继承 

3.第17条:要么为继承而设计,并提供文档说明,要么就禁止继承

4.第18条:接口优于抽象类

  现有的类可以很容易被更新,以实现新的接口。

 接口是定义mixin(混合类型)的理想选择。

 接口允许我们构造非层次结构的类型框架。

5.第19条:接口只用于定义类型

6.第20条:类层次优于标签类

7.第21条:用函数对象表示策略

 函数对象:一个类仅导出通过对象引用实现的方法,她的实例实际上就等同于一个指向该方法的指针。

 函数指针的主要用途是实现策略模式。

8.第22条:优先考虑静态成员类

 嵌套类:静态成员类,非静态成员类,匿名类和局部类

 内部类:非静态成员类,匿名类和局部类

 

第五章 泛型

1.第23条:请不要在新代码中使用原生态类型

 原生态类型:不带任何实际类型参数的泛型名称。

 如果使用原生态类型,就失掉了泛型在安全性和表述性方面的所有优势。

 虽然你可以将List<String>传递给类型List的参数,但是不能将它传给类型List<Object>的参数。泛型有子类型化的规则,LIst<String>是原生态类型List的一个子类型,而不是参数化类型LIst<Object>的子类型。因此,如果使用像List这样的原生态类型,就会失掉类型安全性,但是如果使用像List<Object>这样的参数化类型,则不会。

 无限制的通配符类型:要使用泛型,但不确定或者不关心实际的类型参数,可以使用一个问号代替。

该规则的两个例外:(源于“泛型信息可以在运行中被擦除”)

(1)在类文字中必须使用原生态类型。规范不允许使用参数化类型(虽然允许数组类型和基本类型):List.class,String[].class和int.class都合法,但List<String>.class和List<?>.class则不合法。

(2)在参数化类型而非无限制通配符类型上使用instanceof操作符是非法的。用无限制通配符类型代替原生态类型,对instanceof操作符的行为不会产生任何影响。在这种情况下,尖括号(<>)和问号(?)就显得多余了。

if(o instanceof Set){
    Set<?> m = (Set<?>)o;
}

2.第24条:消除非受检警告

 编译器警告:非受检强制转化警告(unchecked cast warnings),非受检方法调用警告,非受检普通数组创建警告,以及非受检转换警告(unchecked conversion warnings)。

 如果无法消除警告,同时可以证明引起警告的代码是类型安全的,只有在这种情况下才可以用一个@SuppressWarnings("unchecked")注解来禁止这条警告。但应始终在尽可能小的范围中使用该注解。

 每当使用SuppressWarnings("unchecked")注解时,都要添加一条注解,说明为什么这么做是安全的。

3.第25条:列表优先于注解

 数组与泛型相比,两个不同点:(1)数组是协变的,泛型是不可变的(2)数组是具体化的,数组在运行时才知道并检查它们的元素类型约束,泛型是通过擦除实现的,所以泛型只在编译时强化它们的类型信息。

4.第26条:优先考虑泛型

 将类泛型化的第一个步骤是给它的声明添加一个或者多个类型参数。

5.第27条:优先考虑泛型方法

 泛型方法的一个显著特性是,无需明确指定类型参数的值,不像调用泛型构造器的时候是必须指定的。编译器通过检查方法参数的类型来计算类型参数的值。

6.第28条:利用有限制通配符来提升API灵活性

 producer-extends,consumer-super(PECS)

7.第29条:优先考虑类型安全的异构容器

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值