zoukankan      html  css  js  c++  java
  • Effective.Java第56-66条(规范相关)

    56.  为所有已公开的API元素编写文档注释

      要正确地记录API,必须在每个导出的类、接口、构造方法、方法和属性声明之前加上文档注释。如果一个类是可序列化的,还需要记录它的序列化形式。

      文档注释在源代码和生成的代码中都应该是可读的通用原则。

      类或接口中的两个成员方法或构造方法不应具有相同的概要描述。

      总结起来就是一句话,文档注释要规范。

    阿里规约如下:

    【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 // xxx 方式。
    【强制】所有的抽象方法(包括接口中的方法) 必须要用 Javadoc 注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
    【强制】所有的类都必须添加创建者和创建日期。
    【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。
    【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途

    57.  最小化局部变量的作用域

      最重要的技术就是在使用变量之前再首次声明变量。

      几乎每个局部变量都应该包含一个初始化器。

    58.  for-each循环优于普通for循环

      for-each官方称为增强for循环。如下:看到冒号(:)读作in。下面的循环读作对于elements中的每个元素e。

    for (Element e: elements) {
                
    }

    有三种情况不能使用for-each循环:

    有损过滤:如果需要遍历集合并删除元素不能用,需要使用迭代器。

    转换:如果需要转换集合的部分元素或值,需要用到下标的话需要用普通for循环。

    并行迭代:如果需要并行遍历多个集合,那么需要显示地控制迭代器或索引遍历。可以使用普通for循环。

      for-each循环在清晰度,灵活性和错误预防方面提供了超越传统for循环的优势,而且没有性能损失。

    59.  了解并使用库

      通过使用标准库,你可以利用编写它的专家的知识和以前使用者的经验。

      每个程序员都应该熟悉java.lang、java.util和java.io的基础知识以及其子包。其实java.util.concurrent包也是非常重要的。

      第三方jar包的话有commons-lang、commons-io、commons-collections相关jar包。

      

      总之,不要重复造轮子。如果你需要做一些看起来相当常见的事情,那么库中可能已经有一个工具可以做你想做的事情。

    60.  若需要精确答案就避免使用float和double

      float和double不能再需要精确计算的地方使用,尤其是货币计算。

    比如:

            float num1 = 1.6F;
            float num2 = 0.9255F;
            System.out.println(num1 - num2);

    结果:

    0.67450005

    解决办法:使用BigDecimal,注意使用其String类型的构造方法不要使用float或double,避免在计算中引入不准确的值。

            float num1 = 1.6F;
            float num2 = 0.9255F;
    
            BigDecimal bidnumber1 = new BigDecimal(String.valueOf(num1));
            BigDecimal bidnumber2 = new BigDecimal(String.valueOf(num2));
    
            BigDecimal subtract = bidnumber1.subtract(bidnumber2);
            float floatValue = subtract.floatValue();
            System.out.println(floatValue);

      总之,对于任何需要精确答案的计算,不使用float或double。如果希望系统处理十进制小数点,并且不介意不使用基本类型带来的不便和成本,就使用BigDecimal。使用BigDecimal的另一个好处是,它可以完全控制舍入模式。

    61.  基本数据类型优于包装类型

      自动装箱和自动拆箱模糊了基本类型和包装类型之间的区别,但不会消除它们。主要区别有下面三条:

    第一:基本类型只有它们的值,而包装类型具有与值不同的标识,换句话说,两个相同包装类型具有相同的值和不同的标识。

    第二:基本类型只有全功能值,而包装类型除了基本类型的所有功能值外,还有一个非功能值,即null。(将 == 操作符应用于包装类型几乎都是错误的)

    第三:基本类型比包装类型更节省时间和空间。

      在操作中混合使用基本类型和包装类型时,包装类型就会自动拆箱,如果一个空对象自动拆箱会引发NPE空指针异常。如下:

            Long sum = 0L;
            for (int i = 0; i < 500; i++) {
                sum += i;
            }

      这个程序比它预期的慢的多,因为它意外地声明了一个局部变量(sum),它是包装类型而不是基本类型。变量会被反复的装箱和拆箱,导致产生明显的性能问题。

    什么情况下应该使用包装类型?

      第一个是作为集合中的元素、键值;第二个是进行反射方法调用时必须使用包装类型。

    62.  当使用其他类型更合适时应避免使用字符串

      字符串类型是其他值类型的糟糕替代品。比如int、float就用其类型表示,不能用字符串表示;表示是或否就用布尔类型。

      字符串是枚举类型的糟糕替代品。

      字符串是聚合类型的糟糕替代品。

      总之,当存在或可以编写更好的类型时,应避免使用字符串来表示对象。

    63.    当心字符串链接引起的性能问题

      字符串链接操作(+)是将几个字符串拼接在一起的简便方法。我们也知道字符串的拼接操作是通过生成StringBuilder并调用其append方法进行拼接。

      当拼接项足够多时,考虑使用StringBuilder的append方法代替。

    64.  通过接口引用对象

      如果存在合适的接口类型,那么应该使用接口类型声明参数、返回值、变量和字段。唯一真正需要引用对象的类的时候是使用构造函数创建它的时候。

      如果养成使用接口引用对象的习惯,将会更加灵活。如果决定切换实现,只需在构造函数切换类名(或使用不同的静态工厂)

      注意:如果原实现提供了接口约定的其他特殊方法,并且依赖于该功能,那么只能用该类接收对象。比如:如下代码只能用LinkedList接收对象引用。

            LinkedList<String> lists = new LinkedList<>();
            lists.peekFirst();

      如果没有合适的接口存在,那么类引用对象是完全合适的。比如String等。

    65.  接口优于反射

      核心反射机制 java.lang.reflect 提供对任意类的编程访问。给定一个 Class 对象,你可以获得Constructor、Method 和 Field 实例,分别代表了该 Class 实例所表示的类的构造器、方法和字段。这些对象提供对类的成员名、字段类型、方法签名等的编程访问。
      此外,Constructor、Method 和 Field 实例允许你反射性地操作它们的底层对应项:你可以通过调用 Constructor、Method 和 Field 实例上的方法,可以构造底层类的实例、调用底层类的方法,并访问底层类中的字段。例如,Method.invoke 允许你在任何类的任何对象上调用任何方法(受默认的安全约束)。

      反射允许一个类使用另一个类,即使在编译前者时后者并不存在。然而,这种能力是有代价的:

    (1)失去了编译时类型检查的所有好处,包括异常检查。

    (2)执行反射访问所需的代码笨拙又冗长。

    (3)性能降低。反射比普通方法调用慢得多。

       有一些复杂的程序需要用到反射,比如代码分析工具和依赖注入框架。

      通过非常有限的形式使用反射,你可以获得反射的许多好处,同时花费的代价很少。

      反射的合法用途(很少)是管理类对运行时可能不存在的其他类、方法或字段的依赖关系。如果编写的程序必须在编译时处理未知 类,则应该尽可能使用反射实例化对象,并在编译时已知的接口或超类访问对象。(比如静态工厂的反射创建对象)

    66.  明智审慎地本地方法

      Java本地接口(JNI)允许Java调用本地方法,这些方法是c或c++编写而成。本地方法一般有三种用途:提供对特定于平台的设施的访问、提供对现有本地代码库的访问、通过本地语言辨析应用程序中注重性能的部分以提高性能。

      为了提高性能,很少建议使用本地方法。

      

  • 相关阅读:
    7深入FDOFDO概念
    IP 地址输入控件
    如何在设计时公开复合控件内的子控件
    Hello! CnBlogs... ...
    十句话,我竟然看了好久
    Linux下剪切命令
    Linux下拷贝命令
    Linux下新建文件夹命令
    Linux下*.tar.gz文件解压缩命令
    项目管理四条转载
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/11084004.html
Copyright © 2011-2022 走看看