第47条:了解和使用类库

Top 100 Java Libraries on Github 2016

Library Number of Projects Type % of projects
junit.junit 2412 Testing 62.45% Total Projects Tested 3,862
org.slf4j.slf4j-api 895 Logging 23.17% Unique Repos Used 12,059
com.google.guava.guava 650 Utilities 16.83% Total Records 47,251
log4j.log4j 615 Logging 15.92% Avg. repos per project 12.23
commons-io.commons-io 537 Utilities 13.90%
org.slf4j.slf4j-log4j12 479 Logging 12.40%
org.mockito.mockito-all 394 Mocks 10.20%
commons-lang.commons-lang 369 Utilities 9.55%
ch.qos.logback.logback-classic 342 Logging 8.86%
org.apache.commons.commons-lang3 327 Utilities 8.47%
javax.servlet.servlet-api 323 Java Extension 8.36%
org.apache.httpcomponents.httpclient 295 Web 7.64%
org.springframework.spring-context 290 Utilities 7.51%
com.fasterxml.jackson.core.jackson-databind 277 Parsing 7.17%
commons-codec.commons-codec 260 Utilities 6.73%
org.mockito.mockito-core 260 Mocks 6.73%
org.springframework.spring-test 259 Testing 6.71%
joda-time.joda-time 248 Utilities 6.42%
com.google.code.gson.gson 246 Parsing 6.37%
org.testng.testng 234 Testing 6.06%

第48条:如果需要精确的答案,请避免使用float和double

float和double类型主要是为了科学计算和工程计算而设计的。它们执行二进制浮点运算( binary floating-point arithmetic ),这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们并没有提供完全精确的结果,所以不应该被用于需要精确结果的场合。float和double类型尤其不适合用于货币计井,因为要让一个float或者double精确地表示0.1(或者10的任何其他负数次方值)是不可能的。

遗憾的是,它输出的结果是$0.61000000000000000001.

总而言之,对于任何需要精确答案的计算任务,请不要使用float或者double。如果你想让系统来记录十进制小数点,并且不介意因为不使用基本类型而带来的不便,就请使用BigDecimal。使用BigDecima!还有一些额外的好处,它允许你完全控制舍人,每当一个操作涉及舍入的时候,它允许你从8种舍入模式中选择其一。如果你正通过法定要求的舍入行为进行业务计算,使用Bigpecimal是非常方便的。如果性能非常关键,并且你又不介意自己记录十进制小数点,而且所涉及的数值又不太大,就可以使用int或者long。如果数值范围没有超过9位{进制数字,就可以使用int;如果不超过18位数字,就可以使用long。如果数值可能超过18位数字,就必须使用BigDecimal.

第49条:基本类型优先于装箱基本类型

这个程序运行起来比预计的要慢一些,因为它不小心将一个局部变量(sum)声明为是装箱基本类型Long, 而不是基本类型long. 程序编译起来没有错误或者警告,变量被反复地装箱和拆箱,导致明显的性能下降。

那么什么时候应该使用装箱基本类型呢?它们有几个合理的用处。第一个是作为集合中的元素、键和值。你不能将基本类型放在集合中,因此必须使用装箱基本类型。这是一种更通用的特例。在参数化类型中,必须使用装箱基本类型作为类型参数,因为Java不允许使用基本类型。例如,你不能将变量声明为ThreadLocal类型,因此,必须使用ThreadLocal代替。最后,在进行反射的方法调用(见第53条)时,必须使用装箱基本类型。

第50条:如果其他类型更适合,则尽量避免使用字符串

经常被错误地用字符串来代替的类型包括基本类型、枚举类型和聚集类型。

  • 宇符串不适合代替其他的值类型。

  • 字符串不适合代替枚举类型。

  • 字符串不适合代替聚集类型。
    如果一个实体有多个组件,用一个字符串来表示这个实体通常是很不恰当的。例如,下面这行代码来自于真实的系统—标识符的名称已经被修改了,以免发生纠纷:

这种方法有许多缺点。如果用来分隔域的字符也出现在某个域中,结果就会出现混乱。为
了访问单独的域,必须解析该字符串,这个过程非常慢,也很繁琐,还容易出错。你无法提供equals, toString或者compareTo方法,只好被迫接受String提供的行为。更好的做法是,简单地编写一个类来描述这个数据集,通常是一个私有的静态成员类(见第22条).

第53条:接口优先千反射机制

核心“反封机制(core reflection facility) java.lang.reflect, 提供了“通过程序来访问关于已装载的类的信息”的能力。给定一个CIass实例,你可以获得Constructor, Method和Field实例,分别代表了该Class实例所表示的类的Constructor(构造器)、Method(方法)和Field(域)。这些对象提供了“通过程序来访问类的成员名称、域类型、方法签名等信息”的能力。

而且,Constructor, Method和Field实例使你能够通过反扮机制操作它们的底层对等体:通过调用Constructor, Method和Field实例上的方法,可以构造底层类的实例、调用底层类的方法,并访问底层类中的域。例如,Method.invoke使你可以调用任何类的任何对象上的任何方法(遵从常规的安全限制)。反射机制(reflection)允许一个类使用另一个类,即使当前者被编译的时候后者还根本不存在。然而,这种能力也要付出代价:

  • 丧失了编译时类型检查的好处
    包括异常检查。如果程序企图用反射方式调用不存在的或者不可访问的方法,在运行时它将会失败,除非采取了特别的预防措施.
  • 执行反射访问所需要的代码非常笨拙和冗长
    编写这样的代码非常乏味,阅读起来也很困难。
  • 性能损失
    反射方法调用比普通方法调用慢了许多。具体慢了多少,这很难说,因为受到了多个因素的影响。在我的机器上,速度的差异可能小到2倍,也可能大到50倍。

有一些复杂的应用程序需要使用反射机制。这些示例中包括类浏览器、对象监视器、代码分析工具、解释型的内嵌式系统。在RPC(远程过程调用)系统中使用反射机制也是非常合适的。

第54条:谨慎地使用本地方法

Java Native Interface (JNI)允许Java应用程序可以调用本地方法( native method ) ,所谓本地方法是指用本地程序设计语言(比如C或者C++)来编写的特殊方法。本地方法在本地语言中可以执行任意的计算任务,并返回到Java程序设计语言。

从历史上看,本地方法主要有三种用途。它们提供了“访问特定于平台的机制”的能力,比如访问注册表(registry)和文件锁(file lock)。它们还提供了访问遗留代码库的能力,从而可以访问遗留数据(legacy data)。最后,本地方法可以通过本地语言,编写应用程序中注重性能的部分,以提高系统的性能。

使用本地方法来提高性能的做法不值得提倡
使用本地方法有一些严重的缺点口因为本地语言不是安全的,所以,使用本地方法的应用程序也不再能免受内存毁坏错误的影响。因为本地语言是与平台相关的,使用本地方法的应用程序也不再是可自由移植的。使用本地方法的应用程序也更难调试。在进入和退出本地代码时,需要相关的固定开销,所以,如果本地代码只是做少量的工作,本地方法就可能降低(decrease)性能。最后一点,需要“胶合代码”的本地方法编写起来单调乏味,并且难以阅读。

第56条:遵守普遍接受的命名惯例

对于首字母缩写。到底应该全部大写还是只有首字母大写,没有统一的说法。虽然大写更常见一些,但还是强烈建议采用仅有首字母大写的形式:即使连续出现多个首字母缩写的形式,你仍然可以区分出一个单词的起始处和结束处。
下面这两个类名你更愿意看到哪一个,HTTPURL还是HttpUrl ?

类型参数名称通常由单个字母组成。这个字母通常是以下五种类型之一:T表示任意的类型,E表示集合的元素类型,K和V表示映射的键和值类型,X表示异常。任何类型的序列可以是T, U, V或者T1, T2, T3.

对于返回boolean值的方法。其名称往往以单词“is”开头,很少用has。

《Effective Java》第8章 通用程序设计的更多相关文章

  1. 《Effective Java》学习笔记 —— 通用程序设计

    本章主要讨论局部变量.控制结构.类库.反射.本地方法的用法及代码优化和命名惯例. 第45条 将局部变量的作用域最小化 * 在第一次使用的它的地方声明局部变量(就近原则). * 几乎每个局部变量的声明都 ...

  2. Effective Java 读书笔记之七 通用程序设计

    一.将局部变量的作用域最小化 1.在第一次使用变量的地方声明 2.几乎每个变量的声明都应该包含一个初始化表达式:try-catch语句是一个例外 3.使方法小而集中是一个好的策略 二.for-each ...

  3. Effective Java 学习笔记----第7章 通用程序设计

    第7章 通用程序设计 第29条 将局部变量的作用域最小化     使一个局部变量的作用域最小化,最有力的技术室在第一次使用它的地方声明.   第30条 了解和使用库      效率提高.如果你不知道库 ...

  4. EFFECTIVE JAVA 第十一章 系列化

    EFFECTIVE  JAVA  第十一章  系列化(将一个对象编码成一个字节流) 74.谨慎地实现Serializable接口 *实现Serializable接口付出的代价就是大大降低了“改变这个类 ...

  5. effective java 第2章-创建和销毁对象 读书笔记

    背景 去年就把这本javaer必读书--effective java中文版第二版 读完了,第一遍感觉比较肤浅,今年打算开始第二遍,顺便做一下笔记,后续会持续更新. 1.考虑用静态工厂方法替代构造器 优 ...

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

    本章主要讲了以下几条基本的JAVA编程原则: 1.将局部变量的作用域控制在最小,在使用时才定义 2.for-each优于for循环 有三个例外(1,2点主旨就是,for each只能用于读取,不能用于 ...

  7. 《Effective Java 2nd》第8章 通用程序设计

    目录 第45条 将局部变量的作用域最小化 第46条 for-each循环优先于传统的for循环 第47条 了解和使用类库 第48条 如果需要精确的答案,避免使用float和double 第49条 基本 ...

  8. [Effective Java]第三章 对所有对象都通用的方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. 对于所有对象都通用方法的解读(Effective Java 第三章)

    这篇博文主要介绍覆盖Object中的方法要注意的事项以及Comparable.compareTo()方法. 一.谨慎覆盖equals()方法 其实平时很少要用到覆盖equals方法的情况,没有什么特殊 ...

随机推荐

  1. bzoj 3709: [PA2014]Bohater 贪心

    题目: 在一款电脑游戏中,你需要打败\(n\)只怪物(从\(1\)到\(n\)编号).为了打败第\(i\)只怪物,你需要消耗\(d_i\)点生命值,但怪物死后会掉落血药,使你恢复\(a_i\)点生命值 ...

  2. webpack里CommonJS的require与ES6 的module.exports加载模块有何不同

    只需明白commonjs的规则即可,import会被转化为commonjs格式的,babel默认会把ES6的模块转化为commonjs规范的. import vue from 'vue'; //等价于 ...

  3. vertex shader must minimally write all four components of POSITION

    Though the POSITION semantic must be written out by the vertex shader, it cannot be read in by the p ...

  4. 修改分区后的 Grub rescue

    声明:这里用到的知识不是原创,综合了几篇教程的成果.找的时候比较混乱,所以来源已经不确定.希望原作者见谅. 系统是Windows 8.1 和 Ubuntu 14.04, Windows是先装的, gr ...

  5. Activiti:MalformedByteSequenceException: 3 字节的 UTF-8 序列的字节 3 无效。

    在win下开发,有时编译或运行项目会报3字节的UTF-8序列的字节3无效. 解决该问题的办法 1.将xml头文件改为GBK编码方式 ,我这里不OK <?xml version="1.0 ...

  6. Celery-4.1 用户指南: Configuration and defaults (配置和默认值)

    这篇文档描述了可用的配置选项. 如果你使用默认的加载器,你必须创建 celeryconfig.py 模块并且保证它在python路径中. 配置文件示例 以下是配置示例,你可以从这个开始.它包括运行一个 ...

  7. rsync 简单使用 非默认ssh端口 分别从远程获取及推送本地的文件到远程

    rsync: did not see server greetingrsync error: error starting client-server protocol (code 5) at mai ...

  8. python ConfigParser 读取配置文件

  9. HtmlHelper(辅助产生HTML之用)

    弱类型: 1.使用HTML辅助方法输出超链接 (1)在View中输出ASP.NET MVC的超链接通常会用Html.ActionLink辅助方法,该方法用于产生文字链接,其文字部分会自动进行HTML编 ...

  10. samba Nginx

    1.samba 2.nfs 3.crond 4.nginx ifconfig yum install net-tools -y ifconfig #查看所有已激活的网卡信息 ifconfig eth0 ...