Effective Java笔记第一章创建和销毁对象
引言
1.java语言支持四种类型:接口(interface),类(class),数组(array)和基本类型(primitive)。
2.接口(interface),类(class),数组(array)被称为引用类型,类实例和数组是对象。
3.类的成员由他的域(field),方法(method),成员类(member class)和成员接口(member interface)组成。
4.方法的签名(signature)由它的名称和所有参数类型组成,不包括返回类型。
5.术语中的API是指类,接口,构造器(constructor),成员和序列化形式(serialized form)。
6.接口中不能有静态方法。
第一节:考虑用静态工厂方法代替构造器
1.类可以通过静态工厂方法来提供他的客户端,而不是通过构造器。
2.静态工厂方法和构造器相比的四大优势
1)静态工厂方法有名称,当一个类需要多个带相同签名的构造器时,就用静态工厂方法代替构造器,并慎重选择名称以便区分。
2)静态工厂方法不必每次调用他们的时候都创建一个新的对象,使不可变类可以使用预先构建好的实例,或者将构建好的实例缓存,避免创建不必要的重复对象,可以为重复的调用返回相同对象。
3)静态工厂方法可以返回原返回类型的任何子类型的对象,具有灵活性。使得API可以返回对象同时又不会使对象的类变为公有,适用于基于接口的框架。可以要求客户端通过接口来引用被返回的对象,而不是通过它的实现类,这是个好习惯。
4)静态工厂方法在创建参数化类型实例的时候,使代码变得更简洁。在调用参数化类的构造器时,通常要求两次提供类型参数。
举个例子
Map<String,List<String>> map=new HashMap<String,List<String>>();
假设HashMap中有以下这个静态工厂
public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}
我们就可以用以下简介的代码代替
Map<String,List<String>> map=HashMap.newInstance();
3.服务提供者框架
服务提供者框架中有三个重要组件:服务接口(Service Interface),这是提供者实现的;提供者注册API(Provider Registration API),这是系统用来注册实现的,让客户端访问他们的;服务访问API(Service Access API),是客户端用来获取服务的实例的;第四个组件是可选的:服务提供者接口(Service Provider Interface),这些提供者负责其服务实现的实例,如果没有服务提供者接口,就按照类名称注册,并通过反射方式进行实例化。
简单实例
//Service Interface 服务接口
public interface Service {
String demo();
}
//Service Provider Interface 服务提供者接口
public interface Provider {
Service newServcie() ;
}
public class Services {
//防止实例化
private Services(){};
//全局变量
private static final Map<String,Provider> providers=new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME="<def>";
//Provider Registration API 提供者注册API
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p);
}
public static void registerProvider(String name,Provider p){
providers.put(name,p);
}
//Service access API 服务访问API是灵活的静态工厂,构成了服务提供者框架的基础。
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Provider provider = providers.get(name);
if(provider==null){
throw new IllegalArgumentException("No provider registered with name " + name);
}
return provider.newServcie();
}
}
//测试
public class Test {
public static void main(String[] args) {
Services.registerDefaultProvider(DEFAULT_PROVIDER);
Service service1 = Services.newInstance();
System.out.println(service1);
Services.registerProvider("aa",DEFAULT_PROVIDER);
Service aa = Services.newInstance("aa");
System.out.println(aa);
}
private static Provider DEFAULT_PROVIDER = new Provider() {
@Override
public Service newServcie() {
return new Service() {
@Override
public String demo() {
return "ccccc";
}
};
}
};
}
4.静态工厂方法的两大缺点
1)类如果不含公有的或者受保护的构造器,就不能被子类化。
2)静态工厂方法和其他的静态方法实际上没有任何区别。