Effective Java

创建和销毁对象

1.考虑用静态工厂方式代替构造器(P7)

static factory method:类提供一个公有的返回实例的静态方法。

http://blog.csdn.net/mingyunduoshou/article/details/6149758

优点:

有名称;

不必在每次调用他们的时候都新建一个新的对象;

可以返回原来返回类型的任何子类型对象;

在创建参数化类型实例的时候,代码变得很简洁.

缺点:

与其他的静态方法没有明显的区别,使用户难以识别类中到底哪些静态方法专门负责返回类的实例;

如果将要创建的对象的构造方法是私有的或是default的,就有可能不能创建该对象。

2.遇到多个构造器参数的时候考虑用bulider()

程序员喜欢用重叠构造器(telescoping constructor):加参数麻烦,给参数赋值也麻烦,调用者调用也麻烦,参数添加了也麻烦。

JavaBeans模式:创建实例很容易。但是构造过程被分到了几个调用中,使JavaBeans状态不一致。

bulider()模式:把一个复杂对象构建与表示分离,使得同样的构造过程可以创建出不同的表示。

类与接口

使类和成员的可访问权限最小化。
如果方法中覆盖了超类的一个方法,子类中的访问级别就不允许低于超类中的访问权限
这样就有可以确保任何可使用超类实例的地方都可以使用子类的实例

公有类中使用访问方法而不是公有域。
公有类永远别暴露自己的可变的域(线程不安全)!即使是final的,if暴露了,以后想改变其内部表示法也是不可能了,因为公有类的客户端早已经传布世界。

使可变性最小化(immutable)
简单实现:类final,成员变量 private final化 or 类public,然后使用静态工厂模式。注意这压根有哪些好处。
典型举例:String,Bigdecimal
有许多不可变类拥有一个或多个非final域:此时可以延迟初始化:将一些开销昂贵的计算结果缓存在域中,以备将来再次调用时使用。

复合优于继承
继承打破了封装性。只有当子类是超类的子类型时候才适合继承。
composition:在新的类中加一个私有域,它引用现有域的一个实例。
反例:stack:vector properties:hashtable
构造器决不能调用可被覆盖的方法

接口优于抽象类

区别:

1.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.设计层面上的区别

  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

why?
1,现有的类可以很容易被更新,以实现新的接口。
2.接口是定义mixin(混合接口)的理想选择
3,接口允许我们构造非层次结构的类型框架(继承容易组合爆炸)
简而言之,接口通常是定义允许多个实现的类型的最佳途径,if我们到处了一个重要的接口,就应该坚决考虑同时提供骨架实现类


接口只用于定义类型,而不能用来导出常量。
why:
1.泄漏实现细节 2.对用户来说并没有什么价值
如何改善?(为什么常量接口不好)
http://www.360doc.com/content/14/1210/17/16650130_431828218.shtml


类层次优于标签类(所谓的标签即 域)
http://blog.csdn.net/partner4java/article/details/7397075
标签类充斥这样板代码,各种乱七八糟的功能记在了一个单一的类中,破坏了可读性,内存占有也增加了。
为了将标签类转为类层次,首先要为标签类的中的每个方法都定义一个包含抽象方法的抽象类。

用函数对象表示策略
http://blog.csdn.net/partner4java/article/details/7404968

优先考虑静态成员类

嵌套类:静态成员类;内部类:非静态成员类;匿名类;局部类。
http://www.cnblogs.com/aigongsi/archive/2012/04/24/2467183.html

why?
非静态成员类的每个实例都隐含着与外围类的一个外围实例(enclosing instance)相关联

泛型




































原文地址:https://www.cnblogs.com/kydnn/p/5125727.html