- 浏览: 254817 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
aquarion:
非常感谢,解决了我的问题
Perspective 自定义设置扩展点 -
zheng_zhen:
好文章,进一步问您一下,请问自己实现的run/debug如何能 ...
【原创】Eclipse Launcher (Run/Debug As 菜单扩展)实现 -
salever:
mwdnjupt 写道http://www.xeclipse. ...
浅析OSGI的bundle依赖 -
mwdnjupt:
http://www.xeclipse.com/?p=1165 ...
浅析OSGI的bundle依赖 -
Tom.X:
插件化、模块化应遵循高内聚、低耦合的原则,尽量不要在各bund ...
浅析OSGI的bundle依赖
Item 1;Consider static factoriy moehtods instead of constructors
考虑使用静态工厂方法代替构造函数
Item 2:Consider a builder when faced with many constructor parameters
当构造函数参数过多时,是否可以使用Builder
一个builder的例子:
医生需要开一个只包含维生素(Vitamin)的处方(Prescription),处方一定包括A,可能包括B1、B2、C、D、E等,可能这个列表还会变化。这个例子用builder pattern实现就是:
Prescription prescriotion = new Prescription.builder(100/**mg*/).vitaminB1(20/**mg*).vitaminE(1000/**mg*/).build(); //开了一个包含100mg维生素A、20mg维生素B1、1000mg维生素E的处方(可能这个患者比较需要维生素E)。vitaminB1(20/**mg*).vitaminE(1000/**mg*/) 这种串联的方式来创建对象是一个特色,让我想起了设计模式里的decorator模式,不过decorator是把一种类型的对象不断地包装,直到得到所需要的对象。
Sandwich sanwich = new MeatSandwich(new VegetableSandwich(new CreamSandwich()));最后我们得到了一个有肉、蔬菜和奶油的三明治。O(∩_∩)O哈哈~
Item 3:Enforce the singleon property with a private constructor or an enum type
实现单例的两种方式——private的构造函数或者使用枚举(enum)? 枚举实现单例倒还没用过- -
Item 4:Enforce noninstantiability with a private constructor
将构造函数设为private来防止实例化,而不是简单讲类声明为abstract,后者允许被继承,子类同样可以被实例化
Item 5:Avoid creating unnecessary objects
避免创建多余的对象,比如 new String("A"); new Integer(1) // insteading using Integer.valueOf(1);
Item 6:Eliminate obsolete object references
释放对象引用
Item 7:Avoid finalizers
避免使用finailizer方法,原因很简单,这个方法一定会执行,但你不知道何时这个方法到底何时执行。
Item 8:Obey the general contact when overriding equals
重写euqals方法时,记得遵守它的每一条规则,具体见http://salever.iteye.com/blog/733705
Item 9:Always override hashCode when you override equals
永远记得在你重写equals时也重写hashCode
Item 10:Always override toString
总是重写toString方法,这会使用的类更人性化
Item 11:Override clone judiciously
在适当的时候重写clone方法
Item 12:Consider implementing Comparable
考虑实现Comparable接口,它提供了一个排序方法,使得对象具有一定的顺序。在对象作为集合类元素的时候,实现这个接口是一个不错的选择。
Item 13:Minimize the accessibility of classes and members
最大程度的控制类和成员的访问权限,能用private的就不用protected,能用protected的就不用public
Item 14:In public classes, use accessor menthods, not public fields
在public的类中,采用通过访问器来访问成员变量
Item 15:Minimize mutablility
最大程度地减小可变性,让对象一旦创建就不可更改,比如String,这样的类更简单,而且天生就是线程安全的。在某些场合下,使用静态工厂方法返回经常使用的常量对象,可以避免重复创建。
总之尽可能的减小类的成员的可变性,能用final的就用final。
Item 16:Favor composition over inheritance
组合优先于继承,如果A、B之间不是is-a的关系,那么不要使用继承,组合往往更加合适。另外,分布在不同的package下的class之间最好也能避免继承。要知道,继承实际上破坏了封装性。
Item 17:Design and document for inheritance or else prohibit it
要么好好的设计继承关系并书写良好的说明文档,要么禁用继承。很多情况下,继承方式成为扩展现有类的首要选择,关于继承,有几点需要注意和提高警惕:
A:构造函数不要调用可能会重写的方法,否则将出现难以预料的逻辑错误;
B:在类中不要轻易调用可能会重写的方法,因为这样会加大子类重写时的复杂度,使用private的帮助方法来代替它们;
C:在遇见Cloneable和Serializable时请绕行,非要实现它们的话,请遵守A、B规则,不要在相关方法内调用可能会重写的方法;
D:好好的制定说明文档吧
其实Item16说的已经说的很明白了,不要万不得已,不要轻易使用继承。
Item 18:Prefer interfaces to abstract classes
优先使用interface,这个item主要讲了interface与抽象类在使用中的优缺点,并非某些参考书上一成不变的什么这个可以有变量,那个只能是有常量。
接口提供多种实现的可能,但是相对抽象类来说,它更“死板”,也更稳定,公共接口一般不允许修改,而且实现接口不会破坏类之间的结构关系,它们之间没有继承关系。当你选择使用抽象类的时候,你就要面临it 17中讲得继承问题了。另外,给接口一个基本实现(Skeletal implementation)是一个不错的选择。
Item 19:Use interfaces only to define types
不要用接口干其他的事,其中最常见的就是用它来定义常量,多方便,可以省略public static 几个关键字。但是作者不建议这么做,因为实现了这个接口的类将会用到这些常量,在未来的版本中,如果这些常量被废弃了,它让然要继续实现它,以保证程序的语法正确,这显然不合适。
选用utility class 或者枚举来代替它吧,接口还是用来定义允许多种实现的类型吧。
Item 20:Prefer class hierarchies to tagged classes
限定一个类只能创建一种实例对象,不要尝试通过添加tag来标记不同类型的实例,如果真的需要在类中使用tag 来区分不同类型的实例,那就使用继承结构。
Tagged class,顾名思义,就是在class中使用一个或多个tag,然后
switch(tag){ case TAG_1: instance = new TaggedClass(TAG_1): case TAG_2: instance = new TaggedClass(TAG_2): ... }
Item 21:Use function objects to represent strategies
使用对象引用来实现策略模式,看了一遍无甚感想
Item 22:Favor satic member classes over nonstatic
优先使用静态内部类作为成员,这一节讲得非常好,将四种内部类分析的很透彻。
public class NestedClass { //static member class private static class StaticNested { } //nonstatic member class private class NonstaticNested { } protected void doSth() { StaticNested sn = new StaticNested(); NonstaticNested nn = new NonstaticNested(); //anonymous class 匿名类 Runnable runable = new Runnable(){ @Override public void run() { } }; // local class 局部类 class LocalClass implements Runnable, Comparable{ @Override public void run() { } @Override public int compareTo(Object o) { return 0; } } LocalClass lc = new LocalClass(); } /** * @param args */ public static void main(String[] args) { StaticNested nsn = new NestedClass.StaticNested(); StaticNested sn = new StaticNested(); NonstaticNested nn = new NestedClass().new NonstaticNested(); } }
上述四种内部类,从使用上说:
A,如果内部类需要从外部访问并且不要求与包含类的实例挂上关系,那么选择静态内部类,它与包含类的实例对象没有关联,可以看成一个稍微复杂一些的静态成员;
B,如果内部类的实例与包含类的示例息息相关,那么使用非静态内部类,
new NestedClass().new NonstaticNested(); //outside NonstaticNested nn = new NonstaticNested();//inside
注意非静态内部类因为与其包含类实例之间的关系,在资源和时间消耗上都远远超过静态类,请慎用;
C,在类不会与外界打交道,很简短而且可以确定不会拿类的名字干点啥的 ,可以选择匿名类,注意一定不要影响了代码可读性,而且匿名类不能有静态成员,只能同时实现一个接口或者继承一个基类;
D,如果匿名类很长,而且可能类名有潜在的作用,那么可以考虑使用局部类,它避免了匿名类的的一些短项,比如可以同时实现二个接口。
Item 23:Don't use raw types in new code
不要使用原始类型参数,比如List,建议使用List<Object> List<?> List<String>
Item 24:Eliminate unchecked warnings
尽可能的减少unchecked 警告信息,对于raw 类型的使用上,如果确信是类型安全的,可以使用@SuppressWarnings("unchecked")来避免警告。
Item 25:Prefer lists to arrays
优先使用list。这一节对于list和array分析的很不错,主要包括以下几个方面:
A,行为上的不同:array在运行时才确定元素的类型,而list(参数化的)在编译的时候就需要检查类型,以保证类型的安全。
B,协同变化性(covariant),指的是array之间因存储元素的不同也会存在父子类型的关系,比如int[]是Object[]的一个子类,那么可以将int[]赋给Object[],而list<Integer>与list<Object>则是两个完全不同的集合。
因此,无法创建泛型l的list类型的数组。
示例:
Object[] objs = new String[1]; String[] strings = new String[1]; int [] ints = new int[1]; objs = strings; objs[0] = 1; //java.lang.ArrayStoreException List<String>[] strs = new List<String>[1]; //Error:Cannot create a generic array of List<String> List<Long> longs = new ArrayList<Long>(); longs.add(10L); Object[] objects = strs; objects[0] = longs; String element = strs[0].get(0);
第一段代码就是针对数组的协同变化性和运行时类型检查,编译完全正确,运行时抛出java.lang.ArrayStoreException,第二段代码针对泛型list的数组,编译即出错。若不出错,想想后面的代码,strs[0].get(0)返回的是Long,而不是String,一个潜在的问题就出现了,ClassCastException。
这里面还讲到一个概念——non-reifiable types:简单的讲一个non-reifiable type就是在运行时包含的信息要少于编译时,比如泛型的list,运行时它不会进行类型检查,而编译时则需要,当然一些特殊的list除外——List<?>。non-reifiable types都不能用来创建数组。
Item 26:Favor generic types
优先考虑泛型的类和接口
Item 27:Favor generic methods
优先考虑泛型的方法
Item28:Use bounded wildcards to increase API flexibility
使用绑定的通配符提升API的灵活性
读完这三个已经内牛满面了,作者Joshua Bloch不愧是Java Collection Framework的创始人,也只有他才能把泛型这个问题分析的如此透彻,很多概念和用法都还不是很了解,哎。。。。
Item 29:Consider typesagfe heterogeneous containers
考虑使用类型安全的混杂容器
Item 30:Use enums to instead of int constants
使用枚举代替整形常量
Item 31:Use instance fields instead of ordinals
使用成员变量来代替使用自然顺序的枚举,特别是ordinal()方法的使用上,尤其要注意。
Item 32:Use EnumSet instead of bit fields
使用EnumSet 代替bit类型的成员变量,就像SWT.NONE,SWT.READ_ONLY。我猜为什么SWT的实现很多都是用bit类型的成员组合,比如new Text(composite, SWT.BORDER | SWT.READ_ONLY),也许是SWT的出现比EnumSet要早缘故,先在我们就可以使用EnumSet.of(Style.BORDER, Style.READ_ONLY)来代替了。
Item 33:Use EnumMap instead of ordinal indexing
EnumMap代替ordinal()方式的索引,他举了一个例子,就是液固气之间的转换,先用二维数组实现,然后用EnumMap<State, EnumMap<State, Transition>>实现,后者的确简洁很多,不过这个例子突然是我想起State模式,好像它用EnumMap实现真实绝配。
Item 34:Emulate extensiable enums with interfaces
看了这一节,唯一的收获是发现enum也可以实现接口,不知道它能不能继承类呢?好像不能,只能实现接口。。。
Item 35:Prefer annotations to naming patterns
优先使用注解(annotation),jdk1.5里添加了annotation这个功能,它的使用和实现与反射(reflect)关系紧密,Junit就是用annotation实现的。至于naming patterns就是说使用命名规则来区分某些特殊功能,比如test开头的函数为测试函数等。
说道反射,突然想起一个问题,Class.forName("XX"),经常发现找不到class,为什么(联系Java Class loader机制)
Item 36:Consistently use the Override annotation
随时给重写的方法加上“Override”
Item 37:User Marker interfaces to define types
Marker interface 指的是没有扩展新方法的新类型,仅仅声明一下它是一个新的类型,但没有扩展行为,比如Cloneable、Serializable等,书中还提到了使用annotation添加类型说明,但是与Marker interface相比,后者的优势是,它显示定义了一种新的类型。
Item 38:Check parameters for validity
检查参数的合法性
Item 39:Make defensive copies when needed
使用defensive copy保护对象的不变性。对于Java来说,引用类型的常量仅限定了其不能被重新赋值,但是仍然有可能修改其属性,调用修改状态的方法,因此对于这种常量,注意使用防御性质的复制来保护其不变性。
注意defensive copy 与 clone()方法的区别
Item 40:Design method signatures carefully
函数签名设置的原则:
1,取名,按照公认的规则取名
2,不要在一个类中放置太多的方法
3,避免太多的参数, 可以通过几种方法来减少参数的个数:子方法,辅助子类,build模式
4,优先使用interface类型的参数,比如对于HashMap,使用Map就行了
5,对于boolean类型的参数,考虑用枚举代替
Item 41:Use overloading judiciously
适当的使用方法重载
Item 42:Use varargs judiciously
明智的使用变长参数
Item 43:Return empty arrays or collections, not nulls
使用空集合代替null返回值,以避免额外的null检查或错误
Item 44:Write doc comments for all exposed API elements
这个是关于API注释的,其中{@code} 和 {@literal} 标签比较有用,其他的暂时用不着呢。。。
Item 45:Minimize the scope of local variables
缩小局部变量的作用域
Item 46:Prefer for-each loops to traditional for loops
使用for-each循环代替传统的for循环
Item 47:Know and use the libraries
理解和使用库,这个作者建议开发者至少熟悉java.lang.*、java.utl.*以及部分的java.io.*下的内容
(待续)
评论
编写具有“防御性质”的readObject方法
Item 77:For instance control, prefer enum types to readResolve
Item 78:Consider serialization proxies instead of serialized instances
明智的使用序列化,这一节开始讲序列化,可惜不是很懂,要补补
Item 75: Consider using a custom serialized form
考虑使用自定义的序列化,而不是默认的
尽量使用concurrency里的工具方法,而不是原始的wait和notify方法。这一节讲了两个java.util.concurrency下的工具集合:concurrenct collection和synchronizer。前者比较常用的是ConcurrentHashMap等,后者则有CountDownLatch和CyclicBarrier,用他们可以很方便的实现线程控制。
Item 70:Document thread safety
用文档明确的说明线程的安全性,有几个级别Immutable、ThreadSafe和ThreadUnsafe。这一节还提到同步控制的几个原则:double-check,如何用private lock object防止拒绝服务攻击等
Item 71:Use lazy initialization judiciously
明智的使用延迟初始化,延迟初始化可以提高性能,但是一定要注意使用的时机。很多时候,正常的初始化就够了。
Item 72:Don't depend on the thread scheduler
不要依靠线程的调度机制,这里还提到线程的个数问题,这个个数与CPU的数量并没有多大的关系,只是记得:线程不要频繁的切换busy-wait状态,以及在不工作的时候停止就行了。
Item 73:Avoid thread groups
thread group 不是一个好东西,最好离它远远地。
同步访问共享的可变数据,这节开始讲同步的常见问题。
Item 67: Avoid excessive synchronization
避免过度的使用同步,主要是在同步中避免使用alien 方法,所谓alien方法,就是可能被子类重写的,或者是可能转交对象控制权的方法(function object)
Item 68: Prefer executors and tasks to threads
并非所有的线程都只能用Thread实现,java.util.concurrent 下面还有Executor和Task等,也可以实现新建线程处理任务,而且,Executor还提供了安全的终止任务的方法shutDown(),看来有必要好好学学java.util.concurrent
根据抽象的程度,抛出合适的异常,这里讲了一个exception translation,所谓的异常翻译,把低级别的异常处理为高级别的异常来抛出,这里的级别是对应抽象的程度而言的。
Item 62: Document all exceptions thrown by each method
对方法抛出的所有异常,都给出详细的说明文档
Item 63: Include failure-capture information in detail messages
在异常的信息中包括失败时的快照信息
Item 64: Strive for failure atomicity
尽力保持程序执行失败的原子性,主要是为了保证对象的状态的正确性,一般的可以通过在方法的最开始进行参数、前置条件的检查等来保证。
Item 65: Don't ignore exceptions
不要忽略异常,即使真的不需要处理,最好也加上注释
注意遵守命名规则,包括字面上和语法上的,关于Java的命名规则,很多地方都讲到了。
Item 57: Use exceptions only for exceptional conditions
除非出现了异常的情况才使用异常(Exception),java的异常处理非常强大,但是需要主要在正确的场合下使用
Item 58: Use checked exceptions for recoverable conditions and runtime
exceptions for programming errors
对于Java中的三种可以catch的类型:checked exception、runtime exception和error,作者建议在出现了异常并且异常可以恢复的,使用checked exception,这样并不影响程序的执行。而后两者的出现将暂停当前执行的线程,如果用户没有处理,那么JVM将终止当前线程,当然你可以根据情况捕获这些异常。
Item 59: Avoid unnecessary use of checked exceptions
不要滥用checked exception
Item 60: Favor the use of standard exceptions
多使用下标准异常吧,比较常用的有:IllegalArgumentException、IllegalStateException、NullPointException、IndexOutOfBoundsException、ConcurrentModificationException、UnsupportedOperationException等
优先使用接口,而不是反射。反射机制是Java的一个特色,但是不要滥用,它相对来说比较慢,出错的几率更高,而且代码的编写和阅读更难。除非对于那些在编译的时候不能确定的class,否则不要轻易使用反射。
Item 54:Use native methods judiciously
明智的使用本地方法
Java提供了JNI 来调用本地方法,以补充平台相关性。有一个原则,不要以提升效率的原因去使用JNI,因为JNI 并非一个提升效率的捷径,相反它更慢,而且容易出错,而且也限制了系统的平台移植性。
Item 55:Optimize judiciously
小心的优化
优化一直是一个津津乐道的话题,对于优化,作者给出三条格言:
1,许多计算机方面的错误都是因为进了没有必要的优化而导致的,包括一些极度愚蠢的错误;
2,不要为了一些细小的效率提升而进行优化,据说97%的情况下不成熟的优化行为才是万恶之源;
3,时刻记得2个优化原则:不要优化;除非你有了一个明确和可行的优化方案
避免在精确进算的时候使用浮点数和双精度数
System.out.println(1.03 - .42); 看看结果就知道了
Item 49:Prefer primitives types to boxed primitives
优先使用原始数据类型
记得有一回面试的时候,面试官还煞有其事的问题box和unbox,好像很高深似地,可惜当时不怎么注意。。。
原始数据类型仅保存值,都有默认的初始化值,而且效率更高,除非为了Collection相关的元素,一般选择使用原始类型就行了。
Item 50: Avoid strings where other types are more appropriate
不要滥用string
Item 51: Beware of performance of string concatenation
字符的连接操作优先使用StringBuffer
Item 52: Refer to objects by their interfaces
除非没有对应的接口,否则使用接口来代替实际的class类型
发表评论
-
Java 技能树
2016-07-25 18:58 796java技能树 -
Java看书笔记
2014-08-07 17:15 725这一篇专用于一些日常的Java读书笔记 先写一点关 ... -
XStream和Jackson的使用优化
2012-12-17 11:09 0marker一下,需要研究一下这2种lib的使用方式。 -
ArrayList与LinkedList的简单比较
2012-07-27 11:07 1544本文同步发表在http://www.xeclipse.com/ ... -
java.lang.System类浅析
2012-07-25 09:58 1903本文同步发表在 http://www.xeclipse.com ... -
Linux/Unix下JFreeChart的NoClassDefFoundError问题
2012-07-04 14:51 1671最近遇到这样一个问题,使用JFreechart 1.0.13开 ... -
【转】常见的开源协议
2011-08-12 15:47 513Mozilla Public License ... -
【转】JDK发布版本时间以及代号
2011-06-20 14:02 1569已发行的版本: 版本号 名称 中文名 发布日期 ... -
最近的apache学习计划
2011-06-09 11:58 1236最近可能会要做一些apache相关的学习和开发工作,有一些pr ... -
Object类wait,notify,notifyAll的使用
2011-05-06 11:02 1468这三个方法是java的基础类Object中定义的。 w ... -
Java nio 整理整理
2011-02-25 17:17 1108看了看Java的nio类库,整理一下思路。 1,Buf ... -
Java 内存的那些事
2011-02-22 10:38 5016虽然Java屏蔽了一下内存 ... -
一些有用的Web Service 地址
2011-02-11 11:11 2215这里记录一下比较有用的Web Service 地址,可能会有用 ... -
【Java】利用HTML生成PDF之问题整理
2011-01-06 14:38 3940首先,技术为apache 的FOP ... -
【转】如何在java程序中设置文件为“隐藏”属性
2010-10-19 10:55 1614引自http://linshiquan.iteye.com/b ... -
【转】字符,字节和编码
2010-10-18 10:09 1198引言 “字符与编码” ... -
Java, 那些美妙的书籍
2010-08-10 15:39 7217整理一下最近看过或者比较有兴趣的Java书籍,以供大家参考 ... -
Object的equals()重写
2010-08-10 14:49 1562JDK1.6 API写道 public boolean e ... -
Object的equals()与hashCode()的关系
2010-08-10 14:37 0笔者在以前Java项目中使用findbugs工具时,经常遇到一 ... -
学习JVM 之 class文件校验器
2010-07-21 11:29 1977JVM中的class文件校 ...
相关推荐
读书笔记:Effective Java中文版 第2版
读书笔记:Effective Java 中文版(第2版)总结 (美)Joshua Bloch 著
这本书的第三版包含了大量更新,涵盖了Java语言和平台的新发展,如Java 8和Java 9的新特性。以下是对《Effective Java》笔记中可能涉及的关键知识点的详细解读: 1. **单例模式**:书中强调了如何正确实现单例模式...
1. **第2章 创建和销毁对象** - 单例模式:讲解了如何正确实现单例类,避免多线程环境下的并发问题。 - 构造函数:强调构造函数应简洁,避免在构造过程中执行复杂操作。 - 工厂方法:介绍工厂方法模式,作为创建...
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
11. **Java EE**:如果PDF深入,可能会介绍Java企业版,包括Servlet、JSP、EJB、JDBC等Web开发技术。 12. **设计模式**:介绍常见的设计模式,如单例、工厂、观察者等,提升代码的可读性和可维护性。 此外,这份...
第三版笔记 章节索引 02 - 创建和销毁对象 03 - 所有对象通用的方法 04 - 类和接口 05 - 泛型 06 - 枚举和注释 07 - Lambda 和流 08 - 方法 09 - 通用编程 10 - 例外 11 - 并发 12 - 序列化 第 2 章 - 创建和销毁...
2. **《Effective Java》**:由Joshua Bloch撰写,是Java开发者的经典之作。书中列举了23个编程实践,讲解如何编写高效、可维护的Java代码。例如,它涵盖了枚举优于常量、避免使用原始类型、优先考虑泛型、以及何时...
├ data_structure 数据结构与算法分析_Java语言描述(第2版) ├ effective_java Effective Java 中文第二版 ├ jvm 深入理解Java虚拟机:JVM高级特性与最佳实践 ├ lambda JAVA 8实战 ├ netty Netty权威指南 ...
3. **《Effective Java》第二版(effective-java-2)**:这是Joshua Bloch的经典之作,书中列举了23个编程项,提供了关于如何编写更高效、可读性更强的Java代码的实用建议。它涉及的主题包括枚举类型、泛型、匿名内部...
《Java框架设计》第一版**(2012):介绍了Java中常用的框架及其设计理念,适合希望深入了解Java框架的开发者。 9. **王映龙.《JavaEE实用教程》**(2011):提供了JavaEE的实际应用场景和解决方案,适合进行Web应用...