目录检索
第2章 创建和销毁对象
第1条:考虑用静态工厂方法代替构造器
第2条:遇到多个构造器参数时要考虑用构建器
第3条:用私有构造器或者枚举类型强化Singleton属性
第4条:通过私有构造器强化不可实例化的能力
第5条:避免创建不必要的对象
第6条:消除过期的对象引用
第7条:避免使用终结方法
第3章 对于所有对象都通用的方法
第8条:覆盖equals时请遵守通用约定
第9条:覆盖equals时总要覆盖hashCode
第10条:始终要覆盖toString
第11条:谨慎地覆盖clone
第12条:考虑实现Comparable接口
第4章 类和接口
第13条:使类和成员的可访问性最小化
第14条:在公有类中使用访问方法而非公有域
第15条:使可变性最小化
第16条:复合优先于继承
第17条:要么为继承而设计,并提供文档说明,要么就禁止继承
第18条:接口优于抽象类
第19条:接口只用于定义类型
第20条:类层次优于标签类
第21条:用函数对象表示策略
第22条:优先考虑静态成员类
第5章 泛型
第23条:请不要在新代码中使用原生态类型
第24条:消除非受检警告
第25条:列表优先于数组
第26条:优先考虑泛型
第27条:优先考虑泛型方法
第28条:利用有限制通配符来提升API的灵活性
第29条:优先考虑类型安全的异构容器
第6章 枚举和注解
第30条:用enum代替int常量
第31条:用实例域代替序数
第32条:用EnumSet代替位域
第33条:用EnumMap代替序数索引
第34条:用接口模拟可伸缩的枚举
第35条:注解优先于命名模式
第36条:坚持使用Override注解
第37条:用标记接口定义类型
第7章 方法
第38条:检查参数的有效性
第39条:必要时进行保护性拷贝
第40条:谨慎设计方法签名
第41条:慎用重载
第42条:慎用可变参数
第43条:返回零长度的数组或者集合,而不是:null
第44条:为所有导出的API元素编写文档注释
第8章 通用程序设计
第45条:将局部变量的作用域最小化
第46条:for-each循环优先于传统的for循环
第47条:了解和使用类库
第48条:如果需要精确的答案,请避免使用float和double
第49条:基本类型优先于装箱基本类型
第50条:如果其他类型更适合,则尽量避免使用字符串
第51条:当心字符串连接的性能
第52条:通过接口引用对象
第53条:接口优先于反射机制
第54条:谨慎地使用本地方法
第55条:谨慎地进行优化
第56条:遵守普遍接受的命名惯例
第9章 异常
第57条:只针对异常的情况才使用异常
第58条:对可恢复的情况使用受检异常,对编程错误使用运行时异常
第59条:避免不必要地使用受检的异常
第60条:优先使用标准的异常
第61条:抛出与抽象相对应的异常
第62条:每个方法抛出的异常都要有文档
第63条:在细节消息中包含能捕获失败的信息
第64条:努力使失败保持原子性
第65条:不要忽略异常
第10章 并发
第66条:同步访问共享的可变数据
第67条:避免过度同步
第68条:executor和task优先干线程
第69条:并发工具优先于wait和notify
第70条:线程安全性的文档化
第71条:慎用延迟初始化
第72条:不要依赖于线程调度器
第73条:避免使用线程组
第11章 序列化
第74条:谨慎地实现Serializable接口
第75条:考虑使用自定义的序列化形式
第76条:保护性地编写readObject方法
第77条:对于实例控制,枚举类型优先于readResolve
第78条:考虑用序列化代理代替序列化实例
考虑静态构造方法
这里的静态构造方法不等于设计模式中的工厂模式
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
优点:
第一个优势是有名称
对于同一个对象,它的构造函数名字是确定的,有时候你需要基于这个类的自定义对象,采用这种静态构造方法,命名的时候可以很清楚的把这个对象的特点说清楚。
不必每次调用都创建一个新的对象
你可以缓存起来,进行重复利用,每次返回的时候都返回同一个对象,如上面的代码所示,并没有使用new,直接返回的是已经有的对象
可以返回原类型的任何子类
适用于基于接口的框架。而且可以使API返回的对象的类是私有的(使用构造函数肯定不行)。
服务者提供框架
静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可不存在,构成了服务者提供框架
//服务提供者接口,用来提供服务
//这个接口时可选的,如果没有,下面的Map集合就可以直接存放Service对象
public interface Provider {
Service newService();
}
//服务接口, 用来写具体的服务内容
public interface Service {
// Service-specific methods go here
}
public class Services {
private Services() {
} // Prevents instantiation (Item 4)
// Maps service names to services
//服务的注册和访问
//用一个Map来存放提供这的名字和提供者的对象
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
// Provider registration API
//注册默认的提供者
public static void registerDefaultProvider(Provider p) {
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
//所谓注册就是在加入Map
public static void registerProvider(String name, Provider p) {
providers.put(name, p);
}
// Service access API
//使用这个方法创建实例
public static Service newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
//创建的时候看缓存里有没有provider
public static Service newInstance(String name) {
Provider p = providers.get(name);
if (p == null)
throw new IllegalArgumentException(
"No provider registered with name: " + name);
return p.newService();
}
}
测试
public class Test {
public static void main(String[] args) {
//测试的时候先注册,然后在再创建相应地对象,这里的provider的使用内部类
//由provider返回具体的service实例
// Providers would execute these lines
Services.registerDefaultProvider(DEFAULT_PROVIDER);
Services.registerProvider("comp", COMP_PROVIDER);
Services.registerProvider("armed", ARMED_PROVIDER);
// Clients would execute these lines
//调用Service的toString方法
Service s1 = Services.newInstance();
Service s2 = Services.newInstance("comp");
Service s3 = Services.newInstance("armed");
System.out.printf("%s, %s, %s%n", s1, s2, s3);
}
private static Provider DEFAULT_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Default service";
}
};
}
};
private static Provider COMP_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Complementary service";
}
};
}
};
private static Provider ARMED_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Armed service";
}
};
}
};
}
在创建泛型的时候,可以使代码更简单
例如:
//参数你不用再后面重新写一遍了,但实际上HaspMap没有这个方法,这里只是举例说明问题
Map<String, List<String> m = HashMap.newInstance();