zoukankan      html  css  js  c++  java
  • 《Effect Java》 归纳总结

    目录:
    一、创建和销毁对象 (1 ~ 7)
    二、对于所有对象都通用的方法 (8 ~ 12)
    三、类和接口 (13 ~ 22)
    四、泛型 (23 ~ 29)
    五、枚举和注解 (30 ~ 37)
    六、方法 (38 ~ 44)
    七、通用程序设计 (45 ~ 56)
    八、异常 (57 ~ 65)
    九、并发 (66 ~ 73)
    十、序列化 (74 ~ 78)
     
    正文:
     
    第一章: 创建和销毁对象
    1、考虑用静态工厂方法代替构造器
    优:
    ① 有名称
    ② 不必在每次调用它们的时候都创建一个对象
    ③ 可以放回原返回类型的任何子类型的对象
    ④ 在创建参数化类型实例的时候,代码更简洁
    缺:
    ① 类如果不含公有的或受保护的构造器,就不能被子类化
    ② 与其他一般的静态方法无多大区别
    2、 遇到多个构造器参数时要考虑用构造器
    3、用私有构造器或者枚举类型强化 Singleton 属性
    4、通过私有构造器强化不可实例化的能力
    5、避免创建不必要的对象
    6、消除过期的对象引用
    7、避免使用终结方法
     
    第二章: 对于所有对象都通用的方法
    8、覆盖 equals 时请遵守通用约定
    ① 类的每个实例本质上是唯一的
    ② 不关心类是否提供了“逻辑相等”的测试功能
    ③ 超类已经覆盖了 equals, 从超类继承过来的行为对于子类也是合适的
    ④ 类是私有的或包级私有的,可以确定它的 equals 方法永远不会被调用
     
      实现高质量 equals 方法诀窍:
    ① 使用 “==”操作符检查“参数是否为这个对象的引用”
    ② 使用 instanceof 操作符检查“参数是否为正确的类型”
    ③ 把参数转换为正确的类型
    ④ 对于该类中的每个“关键”域,检查参数中的域是否参与该对象中的对应的域相匹配
    ⑤ 当你编写完成了 equals 方法之后,应该判断其是否满足了 对称性、传递性、一致性
        • 覆盖 equals 时总要覆盖 hashCode
        • 不要企图让 equals 方法过于智能
        • 不要将 equals 声明中的 Object 对象器替换为其他的类型
    9、覆盖 equals 时总要覆盖 hashCode
    10、始终要覆盖 toString
    11、谨慎地覆盖 clone
    12、考虑实现 Comparable 接口
     
    第三章:类和接口
    13、使类和成员的可访问性最小化
    14、在公有类中使用访问方法而非公有域
    15、使可变性最小化
    ① 不要提供任何会修改对象状态的方法
    ② 保证类不会被扩展
    ③ 使所有的域都是 final 的
    ④ 使所有的域都成为私有的
    ⑤ 确保对于任何可变组件的互斥访问
    16、复合优先于继承
      简而言之,继承的功能非常强大,但是也存在诸多问题,因为它违背了封装原则。只有当子类和超类之间确实存在子类类型关系时,使用继承才是恰当的。即便如此,如果子类和超类处在不同的包中,并且超类并不是为了继承而设计的,那么继承将会导致脆弱性。为了避免,可以用复合和转发机制来代替继承,尤其是当存在适合的接口可以实现包装类的时候。包装类不仅比子类更加健壮,而且功能也更加强大。
    17、要么为继承而设计,并提供文档说明,要么就禁止继承
    18、接口优于抽象类
    ① 现有的类可以很容易被更新,以实现新的接口
    ② 接口的定义的理想选择
    ③ 接口允许我们构造非层次结构的类型框架
      接口通常是定义允许多个实现的类型的最佳途径。这条规律有个例外,即当演变的容易性比灵活性和功能更为重要的时候。在这种情况下,应该使用抽象类来定义类型,但前提是必须理解并且可以接受这些局限性。如果你导出了一个重要的接口,就应该坚决考虑同时提供骨架实现类。最后,应该尽可能谨慎的设计所有的公有接口,并通过编写多个实现类对它们进行全面的测试。
    19、接口只用于定义类型
        接口应该只被用来定义类型,它们不应该被用来导出常量。
    20、类层次优于标签类
      标签类很少有适用的时候。当你想要编写一个包含显示标签域的类时,应该考虑一下,这个标签是否可以被取消,这个类是否可以用类层次来代替。当你遇到一个包含标签域的现有类时,就要考虑将它重构到一个层次结构中去。
    21、用函数对象表示策略
      要声明一个接口来表示该策略,并且为每个具体策略声明一个实现了该接口的类。当一个具体策略只被使用一次时,通常实现匿名类来声明和实例化这个具体策略类。当一个具体策略类是设计用来重复使用的时候,它的类通常就要被实现为私有的静态成员类,并通过公有的静态 final 域被导出,其类型为该策略接口。
    22、优先考虑静态成员类
      静态成员类、非静态成员类、匿名类、局部类
    ① 如果一个嵌套类需要在单个方法之外仍然是可见的,或者他太长了,不适合于放在内部,就应该使用成员类。
    ② 如果成员类的每个实例都需要一个指向其外围实例的引用,就要把成员类做成非静态的;否则就做成静态的。
    ③ 假设这个嵌套类属于一个方法的内部,如果你只需要在一个地方创建实例,并且已经有一个预置的类型可以说明这个类的特征,就要把它做成匿名类;否则,就做成局部类。
     
    第四章 泛型
    23、请不要在新代码中使用原生态类型
    24、消除非受检警告
      每一条警告都表示可能在运行时片抛出 ClassCastException 异常。要尽最大的努力消除这些警告。如果无法消除非受检警告,同时可以证明引起警告的代码是类型安全的,就可以在尽可能小的范围中,用 @SuppressWarnings("unchecked")注释禁止该警告。要用注释把禁止该警告的原因记录下来。
    25、列表优先于数组
        数组和泛型有着非常不同的类型规则。数组是协变且可以具体化的;泛型是不可变的且可以被擦除的。因此数组提供了运行时的类型安全,当时没有编译时的类型安全,反之,对于泛型也一样。一般来说,数组和泛型不能很好地混合使用。如果你发现自己将它们混合起来使用,并且得到了编译时错误或警告,应该用列表代替数组。
    26、优先考虑泛型
    27、优先考虑泛型方法
    28、利用有限制通配符来提升API 的灵活性
    29、优先考虑类型安全的异构容器
     
    第六章 枚举和注解
    30、用 enum 代替 int 常量
    31、用实例域代替序数
    32、用 EnumSet 代替位域
    33、用 EnumMap 代替序数索引
    34、用接口模拟可伸缩的枚举
    35、注解优先于命名模式
    36、坚持使用 Override 注解
    37、用标记接口定义类型
     
    第七章 方法
    38、检查参数的有效性
    39、必要时进行保护性拷贝
    40、谨慎设计方法签名
      ① 谨慎地选择方法的名称
      ② 不要过于追求提供便利的方法
      ③ 避免过长的参数列表
    41、慎用重载
      “能够重载方法”并不意味着就“应该重载方法”。一般情况下,对于多个具有相同参数数目的方法来说,应该尽量避免重载方法。在某些情况下,特别是涉及构造器的时候,要遵循这条建议也许是不可能的。在这种情况下,至少应该避免这样的情形:同一组参数只需经过类型转换就可以被传递给不同的重载方法。
    42、慎用可变参数
    43、返回零长度的数组或者集合,而不是 null
    44、未所有导出的 API 元素编写文档注释
     
    第八章 通用程序设计
    45、将局部变量的作用域最小化
    46、for-each 循环优先于传统的 for 循环(除了 在过滤、转换、平行迭代下外)
    47、了解和使用类库
    48、如果需要精确的答案,请避免使用 float 和 double
    49、基本类型优先于装箱基本类型
    50、如果其他类型更适合,则尽量避免使用字符串
      ① 字符串不适合代替其他的值类型
      ② 字符串不适合代替枚举类型
      ③ 字符串不适合代替聚集类型
      ④ 字符串不适合代替能力表
    51、当心字符串连接的性能
    52、通过接口引用对象
    53、接口优先于反射机制
      反射的不足:
        ① 丧失了编译时类型检查的好处
        ② 执行反射访问所需要的代码非常笨拙和冗长
        ③ 性能损失
    54、谨慎使用本地方法
    55、谨慎地进行优化
    56、遵守普遍接受的命名惯例
     
    第九章 异常
    57、只针对异常的情况才使用异常
    58、对于可恢复的情况使用受检异常,对于编程错误使用运行时异常
    59、避免不必要地使用受检的异常
    60、优先使用标准的异常
    61、抛出与抽象相对应的异常
    62、每个方法抛出的异常都要有文档
    63、在细节消息中包含能捕获失败的信息
    64、努力使失败保持原子性
    65、不要忽略异常
     
    第十章 并发
    66、同步访问共享的可变数据
    67、避免过度同步
      为了避免死锁和数据破坏,千万不要从同步区域内部调用外来方法。更为一般地讲,要尽量限制同步区域内部的工作量。  
    68、executor 和 task 优先于线程
    69、并发工具优先于 wait 和 notify
    70、线程安全性的文档化
    71、使用延迟初始化
    72、不要依赖于线程调度器
    73、避免使用线程组
     
    第十一章 序列化
    74、谨慎地实现 Serializable 接口
      使用此接口代价:
        ① 一旦一个雷被发布,就大大降低了“改变这个类的实现”的灵活性
        ② 增加了出现 Bug和安全漏洞的可能性
        ③ 随着类发行新的版本,相关的测试负担也增加了  
    75、考虑使用自定义的序列化形式
      使用默认序列化形式缺点:
        ① 它使这个类的导出 API 永远地束缚在该类的内部表示法上
        ② 它会消耗过多的空间
        ③ 它会消耗过多的时间
        ④ 它会引起栈溢出
    76、保护性地编写 readObject 方法
    77、对于实例控制,枚举类型优先于 readResolve
    78、考虑用序列化代理代替序列化实例
  • 相关阅读:
    RN-Android构建失败:Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'AwesomeProject'.
    Android更新包下载成功后不出现安装界面
    真机调试: The application could not be installed: INSTALL_FAILED_TEST_ONLY
    react native 屏幕尺寸转换
    Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值
    React Native安卓真机调试
    git提交代码报错Permission denied, please try again
    The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
    命令行设置快捷命令
    Linux 常用指令
  • 原文地址:https://www.cnblogs.com/jesonjason/p/5824001.html
Copyright © 2011-2022 走看看