Effective Java 总结

创建和销毁对象

01、考虑用静态工厂方法代替构造器
  • 优势1:它们有名称
  • 优势2:不必每次调用他们的时候都创建一个新的对象
  • 优势3:它们可以返回原返回类型的任何子类型的对象
02、遇到多个构造器的参数时要考虑构建器
  • Builder模式
  • 优势1:易于阅读,参数别名
  • 优势2:设置参数的builder生成了一个更好的抽象工厂(Abstract Factory)
03、用私有构造器或者枚举类型强化Singleton属性
  • 枚举
  • 优势1:单例模式
04、通过私有构造器强化不可实例化的能力
  • 比如:工具类
05、避免创建不必要的对象
  • 反面例子:
String str = new String("string"); //创建了二个对象
  • 改进后:
String str = "string";//创建了一个对象
  • 优先使用基本类型而不是使用装箱基本类型,要当心无意识的自动装箱
Long sum = 0L;
for(long i = 0; i < Intager.MAX_VALUE; i++){
    sum += i;
}
System.out.println(sum);
  • 上述代码把 Long sum = 0L;改为 long sum = 0L;效率会提升数倍;
06、消除过期对象引用
Obejct o = null;
07、避免使用终结方法
  • 推荐下面用法
try{

}catch(){

}finally{
    //最终执行
}

对于所有对象都通用的方法

08、覆盖equals时请遵守通用约定
  • 自反性
  • 对称性
  • 传递性
  • 一致性
09、覆盖equals时总要覆盖hashCode
10、始终要覆盖toString
11、谨慎的覆盖clone
12、考虑实现Comparable接口
public interface Comparable<T>{
    int compareTo(T t);
}

类和接口

13、使类和成员的可访问性最小化
14、在公有类中使用访问方法而非公有域
15、是可变性最小化
  • 使类成为不可变 ,遵循五条规则
  • 1、不要提供任何会修改对象状态的方法
  • 2、保证类不会被扩展
  • 3、使所有的域都是final得
  • 4、使所有的域都成为私有的
  • 5、确保对于任何可变组件的互斥访问
16、复合优先于继承
17、要么为继承而设计,并提供文档说明。要么就禁止继承
18、接口由于抽象类
  • jdk1.8之后允许接口定义方法体
public interface Test{

    public void eat();

    defalut String hello(){
        return "Hello Word";
    }

}
19、接口只用于定义类型
20、类层次由于标签类
21、用函数对象表示策略
22、优先考虑静态成员变量

泛型

23、请不要在新代码中使用原生态类型

转换之前最好先instanceof
这里写图片描述

24、消除非受检警告

@SuppressWarnings(“unchecked”)

25、列表优先于数组
  • 区别一:数组是协变的,泛型则是不可变的
  • 区别二:数据是具体化的,泛型则是通过擦除来实现的
// Fails at runtime! 不会报错
Object[] objects = new Long[1];
objects[0] = "I don't fit in";

// Won't compile! 会报错
List<Object> objectList = new ArrayList<Long>();
objectList.add("I don't fit in");

泛型擦除

26、优先考虑泛型
一般来说,将集合声明参数化,以及使用JDK所提供的泛型和泛型方法,这些都不会太困难。
编写自己的泛型会比较困难一些,但是值得花写时间去学习如何编写。
参考java.util.concurrent.DelayQueue

猜你喜欢

转载自blog.csdn.net/baidu_36327010/article/details/80374344