【Effective JAVA】学习笔记

创建和销毁对象

  1. 考虑用静态工厂方法代替构造器
  2. 遇到多个构造器参数时,要考虑用构建器
    注:在lombok插件中 有个 @Builder注解 可以方便生成构建器,建造者模式
  3. 用私有构造器或者枚举类型强化Singleton属性
    注:可以参考单例的几种实现方式,推荐枚举 和 静态类的方法实现,避免饿汉式加载和懒汉式的线程同步问题
  4. 通过私有构造器强化不可实例化的能力。
    注:对于一些工具类 建议加上私有构造器 避免无意义的实例化。
  5. 避免创建不必要的对象
  6. 消除过期的对象引用
    注:常见的导致内存泄漏的情况,a.栈的设计,出栈时未将当前栈位置空。b.缓存,c.监听器的或其他回调,只注册 不取消,可以尝试使用软引用 或者弱引用。
  7. 避免使用终结方法

对所有对象都通用的方法

  1. 覆盖equals时请遵守通用约定
    注:自反性 x.equals(x) == true、对称性、传递性、一致性
  2. 覆盖equals时总要覆盖hashCode
    注:equals相等,hashCode必须相等;但是hashCode相等,equals不一定相等
  3. 始终要覆盖toString方法
    注:为了输出打印对象的可读性,务必覆盖toString对象
  4. 谨慎底覆盖clone
    注:注意深拷贝和浅拷贝
  5. 考虑实现Comparable接口

类和接口

  1. 使类和成员的可访问性最小化
    注:类的几种访问级别
  2. 在公有类中使用访问方法而非公有域
  3. 使可变性最小化
    注:不可变对象尽量用final修饰 包括不可变属性字段,本质上实现线程安全
  4. 复合优先于继承
    注:封装类 ,转发类,装饰模式的应用
  5. 要么为继承而设计,并提供文档说明,要么就禁止继承
  6. 接口由于抽象类
    注:多重组合继承,通用的骨架实现类 如:AbstractSet
  7. 接口只用于定义类型
    注:接口导出常量属于反面例子,以后避免使用,可以使用工具类替代
  8. 类层次由于标签类
  9. 用函数对象表示策略
  10. 优先考虑静态成员类

泛型

  1. 请不要在新代码中使用原生态类型
  2. 消除非受检警告
  3. 列表优先于数组
  4. 优先考虑泛型
  5. 优先考虑泛型方法
  6. 利用有限通配符来提升API的灵活性
  7. 优先考虑类型安全的异构容器

枚举和注解

  1. 用enum代替int常量
  2. 用实例域代替序数
  3. 用EnumSet代替位域
  4. 用EnumMap代理序数索引
  5. 用接口模拟可伸缩的接口
    注:这个实现很妙,可以多参考借鉴
  6. 注解优于命名模式
    注:命名模式早已淘汰
  7. 坚持使用Overrider注解
  8. 用标记接口定义类型

方法

  1. 检查参数的有效性
    注:assert断言会抛出 AssertionError 异常,为Error的子类。公有方法一般不用assert校验
  2. 必要时进行拷贝性保护
    注:各层之间对象转换 DTO,DOMAIN,DO,VO等,各域之间对象相互拷贝
  3. 谨慎设计方法签名
  4. 慎用重载
  5. 慎用可变参数
  6. 返回零长度的数组或者集合,而不是null
  7. 为所有导出的API元素编写文档注释

通用程序设计

  1. 将局部变量的作用域最小化
  2. for-each循环优先于传统的for循环
  3. 了解和使用类库
  4. 如果需要精确的答案,请避免使用float和double
  5. 基本类型优先于装箱基本类型
  6. 如果其他类型更合适,则尽量避免使用字符串
  7. 当心字符串链接的性能
  8. 通过接口引用对象
  9. 接口优先于反射机制
  10. 谨慎地使用本地方法
  11. 谨慎地进行优化
  12. 准守普遍接受的命名惯例

异常

  1. 只针对异常的情况才使用异常
  2. 对可恢复的情况使用受检异常,对变成错误使用运行时异常
  3. 避免不必要地使用受检的异常
  4. 优先使用标准的异常
    注:常见的标准异常有
    IllegalArgumentExcetion: 参数非法
    IllegalStateException: 状态非法
    NullPointerExeption 禁止使用null的情况下 参数为null
    ConcurrentModificationException 并发修改异常
    UnsupportedOperationException 不支持请求操作
  5. 抛出与抽象相对应的异常
  6. 每个方法抛出的异常都要有文档
  7. 在细节消息中包含能捕获失败的信息
  8. 努力是失败保持原子性
  9. 不要忽略异常

并发

  1. 同步访问共享的可变数据
  2. 避免过度同步
  3. executor和task 优先于线程
  4. 并发工具优先于wait和notify
  5. 线程安全性的文档化
  6. 慎用延迟初始化
  7. 不要依赖于线程调度器
    注:尽量确保可运行的线程数量不明显多于CPU核数,否则资源竞争将严重降低性能
  8. 避免使用线程组

序列化

  1. 谨慎的实现Serializable接口
  2. 考虑使用自定义的序列化形式
  3. 保护性的编写readObject方法
  4. 对于实例控制,枚举类型优先于readResolve
  5. 考虑用序列化代理替代序列化实例

你可能感兴趣的:(JAVA基础,设计模式)