effective java
坑铿吭
这个作者很懒,什么都没留下…
展开
-
一.考虑用静态工厂方法代替构造函数
http://tonylian.iteye.com/blog/378830转载 2018-05-21 16:23:42 · 276 阅读 · 0 评论 -
了解和使用库
在java中,通过使用标准库,可以充分利用这些编写标准库的专家的知识,以及在你之前其他人的使用经验。可以使用将精力放在业务上,而不是底层实现上。 有一些常见的标准库你需要了解:java.lang.util,java.io,Collections,Doug lea 的util.concurrent 。。。 总之,不要重复造轮子,这并不能体现你的能力。如果你要做的事情看起来...转载 2018-06-23 07:37:50 · 196 阅读 · 0 评论 -
如果要求精确的答案,请避免使用float和double
对于要求精确答案的计算任务,不要使用float和double。这时应该选择BigDecimal。转载 2018-06-24 08:17:40 · 294 阅读 · 0 评论 -
如果其他类型更合适,则尽量避免使用字符串
字符串不适合代替其他的类型。当从文件读取数据时,通常都是字符串形式,这是应该把字符串中数字用合适的类型表示 字符串不适合代替枚举类型。 字符串不适合代替聚集类型。String compoundKey = className + “#”+i.next() 这样用#来分隔,不如用一个类来替代。...转载 2018-06-24 08:18:16 · 226 阅读 · 0 评论 -
33.了解字符串连接的性能
不要这样连接字符串,字符串是不可变的,每次连接都会创建新的字符串 String s = ""; for(int i = 0; i < 10000; i++){ s += "String"; } 应该利用StringBuilder StringBuilder builder = new...转载 2018-06-24 08:18:33 · 128 阅读 · 0 评论 -
通过接口引用对象
通过接口去引用对象,方便以后相似类的修改 List sub = new Vector();如果原先实现中,并不依赖于Vector的线程安全和一些List中没有的新实现的方法,那么很容易用ArrayList替换 List sub = new ArrayList(); 所以,在通常使用接口去引用对象,这在一定程度上是程序更加灵活。如果没有合适的接口,那么,用类而不是接口来引用...转载 2018-06-24 08:19:02 · 571 阅读 · 0 评论 -
复合优先于继承
继承是实现代码重用的有力手段,但不适当地使用继承会导致脆弱的软件。如果在同一个包下继承比较安全,因为同一个包下,程序员都能看到子类与父类,但当跨包后,如果没有详细的说明文档,可能非常危险。 继承打破了封装性,一个子类依赖于其超类中特定功能的实现细节。如果超类发生变化,那么子类也需要进行相应的变化。如果在修改超类代码后,未告知子类,子类原来运行正常的代码,现在则可能变得不正常。...转载 2018-06-07 18:39:20 · 170 阅读 · 0 评论 -
要么专门为继承而设计,并给出文档说明,要么禁止继承
对于继承与父类的子类,父类的改动,可能会影响子类的,所以如果要编写可被继承的父类,父类的文档必须精确的描述改写每一个方法带来的影响。该文档中所说明的自用模式,以及对于其受保护方法和域所隐含的细节,已经做出了永久的承诺。子类在实现时,不管调用父类的方法,还是覆盖父类中的方法,都应该要注意父类实现的细节,而不仅仅是当做普通的API来调用。 为了允许继承,一个类还必须...转载 2018-06-08 08:55:11 · 164 阅读 · 0 评论 -
需要时使用保护性拷贝
假设类的客户会尽一切手段来破坏这个类的约束条件,在这样的前提下,必须保护性的设计程序 在大多数情况下,都不希望类中的域通过另一个类的方法直接被修改,通常将非可变的参数修饰为private,但有时候会不小心提供这种修改的“机会”class Period{ private final Date start; private final Date end; ...转载 2018-06-15 09:09:00 · 182 阅读 · 0 评论 -
谨慎设计方法的原型
为了使自己写的API发布出去后,别人能够容易使用,应该参考以下这些原则:1.谨慎选择方法的名字:选择一个与功能相符合,并且相似的名字。比如在java中,对于移除,通常命名为remove,比较少用delete2.不要过于追求提供便利的方法:不要定义太多冗余的方法3.避免太长的参数列表:参数列表数,通常最大值被定为3个,如果超过3个,很容易出错。并且,避免定义太多类型相同的参数4.对于...转载 2018-06-16 08:56:06 · 254 阅读 · 0 评论 -
接口优于抽象类
使用抽象类来定义允许多个实现的类型,比使用接口有一个明显的优势:抽象类的演化比接口的演化要容易得多。如果在后续的发行版本中,希望在抽象类中增加一个新的方法,那么,总是可以增加一个具体的方法,它包含了一个合理的默认实现,然后,抽象类的所有已有的实现都自动提供了这个新的方法。但是对于接口,这是行不通的。 要想在一个公有的接口中增加一个方法,而不打破现有的、已经在使用这个...转载 2018-06-09 08:36:10 · 303 阅读 · 0 评论 -
接口只是被用于定义类型
当一个类实现了一个接口的时候,这个接口被用做一个类型,通过此类型可以引用这个类的实例。因此,一个类实现了一个接口,就表明客户可以对这个类的实例实施某些动作。为了任何其他目地而定义接口是不合适的。 有一种接口被称为常量接口,如下:public interface PhysicalConstants{ static final double AVOGADROS_...转载 2018-06-10 10:12:22 · 246 阅读 · 0 评论 -
谨慎地使用重载
重载class CollectionClassifier{ public static String Classify(Set s){ return "set"; } public static String Classify(List l){ return "list"; } public static Strin...转载 2018-06-18 09:22:52 · 168 阅读 · 0 评论 -
返回零长度的数组而不是null
一个从一个取数组值的方法,当数组为空时,返回一个零长度数组而不是null.转载 2018-06-18 09:38:17 · 155 阅读 · 0 评论 -
优先考虑静态成员类
嵌套类是定义在另一个类的内部的类。嵌套类分为:静态成员类、静态成员类、匿名类、局部类 静态成员类:它不依赖于外部成员类的实例,可以单独的创建。它只能访问外部类的静态成员变量和方法,包括private 非静态成员类:它能访问外部类的所有域和方法,所以它不能没有在实例化一个外部类的情况下创建。当非静态类的实例被创建的时候,它和外部类之间的关联关系也随之被建立了起来。每个实例都会包含一个...转载 2018-06-11 09:09:26 · 144 阅读 · 0 评论 -
将局部变量的作用域最小化
使一个局部变量的作用域最小化,最有力的技术是在第一次使用它的地方声明。避免在使用前很早就声明一个局部变量,这样扩大范围,造成误用。 几乎每一个局部变量在声明的时候都应该包含一个初始化表达式。但有时这对try-catch不容易做到,如果try里面才要使用这个变量,而try-catch后,还要继续使用这个变量,那么只能讲这个变量声明在try-catch之前,并且没有合适的初始化。...转载 2018-06-22 08:18:39 · 177 阅读 · 0 评论 -
检查参数的有效性
绝大多数方法和构造函数都会对于传递给它们的参数值有某些限制,比如,索引值不能为非负数,对象引用不能为null。对于编写这些函数,应该考虑对于它的参数有哪些限制,应该把它们写在文档中,并且在这个方法体的起始处,通过显示的检查来实施限制。 有效性检查所需要的适量工作从第一次合法性检查失败中就可以连本带利得到补偿。因为如何为做检查,后面一旦出错,排查错误的花费要大的多...转载 2018-06-14 08:10:32 · 689 阅读 · 0 评论 -
私有构造函数强化singleton属性
single是指这样的类,它只能被实例化一次两种方法:第一种:公有静态成员是一个final域class Elvis{ public static final Elvis INSTANCE = new Elvis(); private Elvis(){} } 这种方法通过Elvis.INSTANCE调用,因为构造函数为private,所以不能...转载 2018-05-21 16:33:59 · 176 阅读 · 0 评论 -
通过私有构造函数强化不可实例化的能力
有时候我们可能希望创建一个工具类,里面包含了一些静态方法和静态域,并不希望它被实例化,可以通过将它的默认构造函数声明为Privateclass UtilityClass{ //private Constructor private UtilityClass(){ //This constructor will never be invoked ...转载 2018-05-22 15:41:36 · 165 阅读 · 0 评论 -
在改写equals的时候请遵守通用的约定
在很多时候,我们都需要去重写equals方法,去满足自己的比较需求,在改写equals时,需要准守以下原则:自反性:对于任意的引用值x,x.equals(x)一定为true对称性:对于任意的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)也一定返回true传递性:对于任意的引用值x、y和z。如果x.equals(y)返回true,并且y.equals(...转载 2018-05-26 19:16:48 · 125 阅读 · 0 评论 -
8.改写equals时总是要改写hashCode
HashMap、HashSet是常用的容器,他们查找的快速性依赖散列表完成的,所以,如果要用对象去作为键,则必须去改写hashCode。通常,规范是如果两个对象的equals值相等,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。 在改写HashCode时,尽量选取非可变的域去生成hashCode,这样避免同一个对象产生不同的hashCode带来的困扰,特...转载 2018-05-26 19:41:15 · 319 阅读 · 0 评论 -
避免创建重复的对象
重复使用同一个对象,而不是每次去创建同一个功能相同的对象。比如前后需要的字符串的字面量相同String s = new String("silly"); 如果每次都这样去创建字符串,那么是非常糟糕的,虽然每次都是“silly”,都每次都是新的字符串应该这样做String s = "No longer silly"; 对于提供了静态工厂方法的类,也可以使用静态工厂方法提供...转载 2018-05-22 16:08:02 · 386 阅读 · 0 评论 -
总是要改写toString
默认的toString方法返回的是@+无符号十六进制的数,在实际中,我们通过重写toString方法,返回我们感兴趣的信息。转载 2018-05-27 18:50:03 · 378 阅读 · 0 评论 -
消除过期的对象引用
java是具有垃圾回收功能的语言,那么我们就不再需要去考虑内存管理的事情了呢?当然不是,当你不小心时,也会导致内存泄漏class Stack{ private Object[] elements; private int size = 0; public Stack(int initialCapacity){ this.elements = ...转载 2018-05-23 18:42:55 · 171 阅读 · 0 评论 -
避免使用终结函数finalize()函数
终结函数并不能保证会及时被执行。从一个对象变得不可到达开始,到它的终结函数被执行,这段时间的长度是任意的、不确定的,有时不一定会被执行(gc只会执行一次)。所以,时间关键的任务不应该由终结函数来完成,并且我们不应该依赖一个终结函数来更新关键性的永久状态。 对于抛出的异常,我们最好是都去捕获,当在终结函数中抛出的异常,都会被忽略掉 所以,最好不要使用终结函数。我们可以使用t...转载 2018-05-23 19:14:02 · 204 阅读 · 0 评论 -
考虑实现Comparable接口
如果你正在编写一个值类,它具有非常明显的内在排序关系,那么应该考虑实现Comparable接口。依赖于比较关系的类包括有序集合类TreeSet和TreeMap,以及工具类Collections和Arrays,它们内部包含有搜索和排序算法。ComparaTo方法的通用约定与equals方法的通用约定具有相似的特征(自反性,对称性,传递性,非空型)。当前这个对象与指定的对象...转载 2018-06-04 15:19:24 · 172 阅读 · 0 评论 -
使类和成员的可访问能力最小化
要区别一个设计良好的模块与一个设计不好的模块,最重要的是,这个模块对于外部的其他模块而言,是否隐藏了内部的数据和其他实现细节。一个设计良好的模块会隐藏所有的实现细节,把它的API与实现清晰的隔离开来。这个概念叫做信息隐藏或者封装 信息隐藏有许多好处:它可以有效的解除一个系统中各个模块间的耦合关系,使得这些模块可以独立地开发、测试、优化、使用、理解和修改等 在java中,提...转载 2018-06-05 10:09:56 · 97 阅读 · 0 评论 -
类代替结构
java是面相对象的语言,在C语言中的结构体,在java中通常用类来代替C语言结构体的数据都是公有的,但在java的类中,可以对数据的作用域进行限制,对于公有类,我们应该将域定义为私有的,并通过公有的set和get方法去访问 而一个类是包级私有的,或者是一个类部类时,因为这就对这个进行了限制,并且程序员对于这些类都是比较容易掌控的,所以有时候,可以将这些情况下的...转载 2018-06-12 10:07:54 · 322 阅读 · 0 评论 -
用类和接口来代替函数指针
在C语言中,支持函数指针,而在java中,省略了它,因为对象的引用可以被用于提供同样的功能。我们在设计具体策略类的时,需要定义一个策略接口,下面以Comparator接口为例public interface{ public int compare(Object o1, Object o2);} 如果一个策略类只被使用给一次,那么通常使用匿名类来声明和实例化这个具体的...转载 2018-06-13 08:49:01 · 471 阅读 · 0 评论 -
支持非可变性
一个非可变类是一个简单的类,它的实例不能被修改。非可变类的存在有许多的理由:非可变类比非可变类更加易于设计、实现和使用,它们更加的安全,不容易出错。为了使一个类成为非可变类,要遵循一下五个原则:1.不要提供任何会修改对象的方法。2.保证没有可被子类改写的方法。通常将类定义成fianl,让它不能被继承。3.使所有的域都是final的。显示的声明你的意图。4.将所有的域都成为私有的...转载 2018-06-06 08:57:04 · 232 阅读 · 1 评论 -
谨慎地改写clone
clone是对对象内域的直接复制,当域中有对象引用时,要分清浅复制和深复制。关于深复制浅复制可以参考:https://blog.csdn.net/qq_27469549/article/details/80501284所以在实现Cloneable接口的时候,要特别小心,所以要实现clone方法,要谨慎。或者退一步,我们根本不去利用克隆去实现,利用其它的途径来实现对象的拷贝,拷...转载 2018-05-30 20:12:26 · 171 阅读 · 0 评论 -
谨慎地使用本地方法
Java Native Interface(JNI)允许java应用去调用本地方法,这些本地方法是非java语言所写(如C/C++)。 使用本地方法主要有3个用途: 1. 提供了“访问与平台相关的设施”的能力,比如访问注册表和文件锁。在并发包concurrent中涉及到锁的很多操作都使用了native方法 2.提供给了访问老式代码库的能力 3.在关键...转载 2018-06-29 09:21:53 · 230 阅读 · 0 评论