Effective Java

来源:互联网 发布:为什么建设网络强国 编辑:程序博客网 时间:2024/05/09 10:37

Effective Java

                              

1.考虑使用静态工厂方法而不是构造函数(Consider static factory methods instead of constructors

例如:Integer类中的:
 public static Integer valueOf(int i) {        if (i >= IntegerCache.low && i <= IntegerCache.high)            return IntegerCache.cache[i + (-IntegerCache.low)];        return new Integer(i);    }

   其它原生类型对应的封装类型都有相应的静态工厂方法,而且每个类都重载了很多静态工厂方法。
一个类采用static factory methods ,而不是构造函数,有以下好处:有一个比较有意义的方法名字;调用方法不必每次都创建一个新对象(缓存);它可以返回类型的子类型;简化创建参数化类型对象实例,让编译器推倒类型;比如:
guava类Maps:
 public static <K, V> HashMap<K, V> newHashMap() {    return new HashMap<K, V>();  }

比较常见的静态工厂函数名:
  • valueOf—Returns an instance that has, loosely speaking, the same value as its parameters. Such static factories are effectively type-conversion methods.
    • of—A concise alternative to valueOf, popularized by EnumSet(Item 32).
    •
getInstance—Returns an instance that is described by the parameters but cannot be said to have the same value. In the case of a singleton,get Instance takes no parameters and returns the sole instance.
    •
newInstance—Like getInstance, except that new Instance guarantees that each instance returned is distinct from all others.
    •
getType—Like getInstance, but used when the factory method is in a different class.Type indicates the type of object returned by the factory method.
    •
newType—Like new Instance, but used when the factory method is in a different class.Type indicates the type of object returned by the factory method.

2.构造函数或者静态工厂函数的参数过多时,可以使用构造器模式(builder pattern)(Consider a builder when faced with many constructor parameters

3.用私有构造函数或者枚举类型强化单例属性(Enforce the singleton property with a private constructor or an enum type

4.利用私有构造函数(也可以在私有构造函数内抛出异常)表达不可实例化的类(Enforce noninstantiability with a private constructor

5.避免创建不必要的对象(对象缓存可以改善)(Avoid creating unnecessary objects

6.清除过期对象的引用(一般情况下,良好的垃圾回收帮我们做了,但过期的对象必须让垃圾回收器知道的前提下)(Eliminate obsolete object references

7.避免使用终结方法(Avoid finalizers

终结方法相关的类与方法有:
重写Object类的方法:
 protected void finalize() throws Throwable { }

调用System类的方法(及Runtime类与此实现相关的方法):
 public static void gc() {        Runtime.getRuntime().gc();    }

public static void runFinalization() {        Runtime.getRuntime().runFinalization();    }

 @Deprecated    public static void runFinalizersOnExit(boolean value) {        Runtime.runFinalizersOnExit(value);    }

8.覆盖equals 方法时要遵守通用约定(Obey the general contract when overridingequals )

9.覆盖equals 方法时总要覆盖hashCode 方法(Always overridehashCodewhen you overrideequals )

10.始终要覆盖toString 方法 (Always override toString )

11.谨慎的覆盖clone方法(Override clonejudiciously

12.考虑实现Comparable接口(Consider implementing Comparable)

13.类及其成员的可访问性最小化(Minimize the accessibility of classes and members

14.在公有类中,要使访问方法访问属性,而非直接使用公共属性(In public classes, use accessor methods, not public fields )

15.尽可能不变性(Minimize mutability

不可变的东西容易设计与实现,而且容易避免错误,得到更多的安全。

16.组合设计优于继承设计(Favor composition over inheritance)

17.要么为继承设计并且提供文档,要么就禁止使用继承设计(Design and document for inheritance or else prohibit it

18.接口优先于抽象类(Prefer interfaces to abstract classes

19.接口只能用于定义类型(Use interfaces only to define types )

常量接口模式是接口的不良使用(The constant interface pattern is a poor use of interfaces.

20.类层次优于标签类(Prefer class hierarchies to tagged classes )


21.用函数对象表示策略(Use function objects to represent strategies

像c、c++语言中的函数指针,java8之前的匿名类,java8中的函数式编程,javascript中的闭包功能一样。

22.优先考虑静态成员类(Favor static member classes over nonstatic

23.请不要在新代码中使用原生态类型,使用泛型(Don’t use raw types in new code )

24.清除非受检警告( Eliminate unchecked warnings)

25.列表优先于数组( Prefer lists to arrays)

26.优先考虑泛型(Favor generic types )

27.优先考虑泛型方法(Favor generic methods

静态工具方法非常适合泛型化。

28.利用有限通配符增加api的灵活性(Use bounded wildcards to increase API flexibility

29.优先考虑类型安全的异构容器(Consider typesafe heterogeneous containers )

30.使用枚举代替int常量( Use enums instead of int constants)

31.用实例域代替序数(Use instance fields instead of ordinals

即枚举的ordinal  方法的返回值,我们如果要使用,必须实例域替换之。

32.用EnumSet 代替位域(Use EnumSetinstead of bit fields

33.用EnumMap 代替序数索引(Use EnumMap instead of ordinal indexing

34.用接口模拟可扩展的枚举(Emulate extensible enums with interfaces )

35.注解优于命名模式(Prefer annotations to naming patterns

这个主要体现是junit框架,现在流行注解模式,而非之前很早版本的命名模式。

36.要使用Override 注解Consistently use theOverrideannotation

37.用标记接口定义类型(Use marker interfaces to define types

例如Serializable 接口,定义了可序列化类型。

方法


38.校验参数的有效性(Check parameters for validity )

39.必要时进行保护性拷贝(Make defensive copies when needed )

40.谨慎的设计方法签名(Design method signatures carefully

谨慎地选择方法的名字(Choose method names carefully)
不要过于追求提供便利的方法(Don’t go overboard in providing convenience methods
避免过长的参数列表(Avoid long parameter lists
对于参数类型,要优先使用接口而非类(For parameter types, favor interfaces over classes

41.慎用重载(Use overloading judiciously

42.慎用可变参数(Use varargs judiciously

43.返回空的数组或集合,而非null(Return empty arrays or collections, not nulls

44.为所有导出的api元素编写文档注释(Write doc comments for all exposed API elements)


General Programming


45.局部便变量的作用域尽可能小(Minimize the scope of local variables

46.优先使用for-each循环语法,而非传统的for循环语法Prefer for-each loops to traditionalforloops

47.了解并且使用类库(Know and use the libraries

48.如果需要精确的数字运算结果,要避免使用float和double(Avoidfloatanddoubleif exact answers are required

这就需要我们要正确使用BigDecimal,int, 或long  进行运算。

 49.基本类型由于对应的封装类型(Prefer primitive types to boxed primitives

50.如果其他类型比较合适,则尽量避免使用字符串(Avoid strings where other types are more appropriate

51.要提防字符串连接的性能(Beware the performance of string concatenation

52.通过接口来引用对应的对象(Refer to objects by their interfaces

53.接口优于反射(Prefer interfaces to reflection

54.谨慎的使用本地方法(Use native methods judiciously

55.谨慎优化(Optimize judiciously

56.遵守普遍的命名规则(Adhere to generally accepted naming conventions

Exceptions

57.仅对对异常的情况下才使用异常(Use exceptions only for exceptional conditions )

58.对于可恢复的情况用受检异常,运行时异常用于程序错误(Use checked exceptions for recoverable conditions and runtime exceptions for programming errors

59.避免不必要的受检异常使用(Avoid unnecessary use of checked exceptions

60.优先使用JDK自带的标准异常(:Favor the use of standard exceptions

61.抛出与抽象对应的异常(Throw exceptions appropriate to the abstraction

62.每个方法所抛出的异常都需要文档化(Document all exceptions thrown by each method

63.异常详细信息中要包含 捕获失败的信息(Include failure-capture information in detail messages

64.努力使失败保持原子性(Strive for failure atomicity

65.不要忽略异常(Don’t ignore exceptions

Concurrency

66.同步访问共享可变数据(Synchronize access to shared mutable data

67.避免过度同步(Avoid excessive synchronization

为了避免活性失败和安全失败,在一个被同步的方法或者代码块中,永远不要放弃对客户端的控制
To avoid liveness and safety failures, never cede control to the client within a synchronized method or block.
通常,你应该在同步区域内做尽可能少的工作(As a rule, you should do as little work as possible inside synchronized
regions


68.executors和tasks 的使用优于线程(Prefer executors and tasks to threads )

69.并发工具类优于wait 和notify (Prefer concurrency utilities towaitandnotify

70.线程安全文档化(Document thread safety

71.慎用延迟初始化(Use lazy initialization judiciously

72.不要依赖线程调度器(Don’t depend on the thread scheduler

73.避免使用线程组(Avoid thread groups


Serialization


74.谨慎地实现序列化接口(Implement Serializablejudiciously

75.考虑使用自定义序列化方式(Consider using a custom serialized form

76.保护性的编写readObject 方法(Write readObjectmethods defensively

77.对于实例控制,枚举类型优于readResolve (For instance control, prefer enum types toreadResolve

78.考虑使用序列化代理,而非序列化实例(Consider serialization proxies instead of serialized instance


性能和效率

  • 不要在循环条件中做重复的计算,每循环一次,重复计算一次浪费CPU

  • 尽可能把变量(可重复利用的值,避免每次创建此类对象)、方法声明为final static类型

  • 缩小变量的作用域

  • 不建立冗余对象

  • 若非必要,不要克隆对象

  • 调整JVM参数以提升性能



1 0
原创粉丝点击