[读书笔记]Effective Java 第8章 通用程序设计方法

Item 45: 将局部变量的作用域最小化

书说: 推荐在第一次使用这个局部变量的时候才初始化。如果初始化的条件还不足,说明还没到时候初始化。例外: try-catch

Item 46: for-each 优于for循环与while循环

主要是for-each 的代码看起来更加简洁, 效率稍微提高。

Item 49: 基本类型优于装箱类型

我觉得看stackoverflow的这一篇帖子说得更清楚一些:

http://stackoverflow.com/questions/5199359/why-do-people-still-use-primitive-types-in-java

总结下来, 有几点原因:

  1. 性能
    对原帖子的代码做了一下修改,直接对两者进行了对比:

     

    输出:

     

    可以看到, 使用装箱类型(Long)耗时4.6s, 如果使用基本类型(long) 只需要0.35s

    这个性能损耗来自对原始的基本类型的封装。需要自动的boxing / unboxing.这里面多少会有性能损失。

    当然, 如果在你的实际应用之中,你觉得这个性能损耗也还行, 也可以~

     

  2. null值
    装箱类型有可能是null, 而原始的基本类型有个默认值(0)比如下面的极端例子, 会抛出NullPointerException 但是编译的时候是检查不出来的:

     

     

     

  3. 装箱类型是奇怪的类!
    比如下面的代码:

     

    输出:

     

    (1) / (2) 是因为他们地址不一样,返回false很好理解。

    为什么(3)返回true, 而(4)返回false?

    • 首先:Integer是类, 正确的比较方法是使用equal
    • 其次:5处在最接近0的256个整数[-128, 127]的区间之中,JVM自动有特殊处理,使其返回的是同一个对象

    把上面的代码改一下,把==改成<

    输出结果就比较符合我们的直觉了,都是输出的false

     

那什么时候才需要使用装箱类型?

在Java之中, 在一些集合类型,比如Map、List,或者参数化类型,比如ThreadLocal<Integer>,不能是基本类型。

本文原创, 原文地址:http://www.flyml.net/2017/03/16/effective-java-ch8-common-design/

Item 52: 通过接口引用对象

如果有合适的接口类型存在, 那么对于参数、返回值、变量和域来说, 都应该使用接口类型进行声明。

 

使用接口而不是直接使用具体的实现类的好处是:灵活

当我们需要变更底层的实现方法的时候,比如需要从ArrayList切换到LinkedList,对外提供的接口、方法等等都不需要变更。

除非真的需要具体类里面的特殊方法, 才使用具体的类。

Item 53: 接口优先于反射机制

Item 56: 遵守普遍接受的命名规则习惯

这部分更详细、更完整的,应该参考:

  1. Google Java 编程规范https://google.github.io/styleguide/javaguide.html
  2. 阿里巴巴的Java编程规范https://bbs.aliyun.com/read/306592.html?page=e

 

本文原创, 原文地址:http://www.flyml.net/2017/03/16/effective-java-ch8-common-design/

 

本文原创, 原文地址:

http://www.flyml.net/2017/03/16/effective-java-ch8-common-design/

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注