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、考虑用序列化代理代替序列化实例
  • 相关阅读:
    现代软件工程 第一周博客作业
    现代软件工程 课题初步调研 在线即时评教系统
    php判断网页是否gzip压缩
    采集练习(五) php 获得chrome扩展 微度新标签页 下的云壁纸(主要是美女壁纸)
    <raspberry pi> raspberry pi 设置wlan 静态ip
    采集练习(三) php 采集当当网图书的数据(初版)
    采集练习(六) python获得chrome扩展 微度新标签页 下的云壁纸
    采集练习(七) php 获得电视节目预告(一周节目)
    采集练习(八) php 获得网易精彩跟贴数据
    采集练习(四) python 获得hao123导航图片分类下的美女图片
  • 原文地址:https://www.cnblogs.com/jesonjason/p/5824001.html
Copyright © 2011-2022 走看看