创建和销毁对象
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 类