后续我会陆陆续续更新《ava程序员开发手册》这一栏目的内容。大家如果觉得对自己有用就点个关注吧。
声明
本文主要来自于《Effective Java (中文第三版)》的读后感与总结,并加上一些我自己的理解,和查阅的资料
示例代码
下面先来简单看一下构造器和静态工厂方法的代码吧!
public class Test_01 {
/**
* 这是公有的有参构造器
*/
String name;
public Test_01(String name){
this.name = name;
}
/**
* 这是公有的无参构造器
*/
public Test_01(){
}
/**
* 这是一个静态工厂方法
*/
public static Test_01 getTest_01Obj(boolean check,String param){
if(check){
return new Test_01();
}else{
return new Test_01(param);
}
}
/**
* 静态工厂方法:获取一个狗的对象
*/
public static Test_01 getDog(){
return new Test_01("Dog");
}
/**
* 静态工厂方法:获取一个空的对象
*/
public static Test_01 getNull(){
return new Test_01();
}
}
这种静态工厂方法和设计模式
中的静态工厂方法是不的,请不要混在一起,可以理解为构造器的封装。
静态工厂方法的优缺点
优点
- 有名字,这样可以更好的表述出某个方法具体返回的是什么样的值。比如:上面代码中的
/**
* 静态工厂方法:获取一个狗的对象
*/
public static Test_01 getDog(){
return new Test_01("Dog");
}
/**
* 静态工厂方法:获取一个空的对象
*/
public static Test_01 getNull(){
return new Test_01();
}
上面举了一个比较简单的例子,参数很短,逻辑也很简单,但也能体现出你在代码中如果写getDog
总比new Test_01("Dog")
更明确。
- 可以控制构造器的滥用和实例对象的数量,我们可以把构造器改为私有的,然后就只能通过静态工厂方法获取实例对象,这样我们就可以对实例对象的创建加以控制。了解单例模式的小伙伴应该都应该很熟悉这种操作。下面是一个线程不安全的单例模式,当然想了解单例模式可以看我的另一篇文章设计模式:单例模式(懒汉模式/饿汉模式)
public class Singleton {
private static Singleton singleton;
private Singleton(){
System.out.println("我是一个单利对象");
}
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
return singleton;
}
return singleton;
}
}
- 它不像构造器本身只能返回对应的实例对象。静态工厂方法可以返回:原返回类型的任何子类型的对象。
例如:Java Collections Framework 的集合接口有 45 个工具实现,分别提供了不可修改的集合、 同步集合,等等。现在的 Collections Framework API 比导出 45 个独立公有类 的那种 现方式 小得多。 - 静态工厂的第五大优势在于,方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。
这句话就不是很好理解了,意思就是说,再返回之前某个类可能是在程序运行过程中自动生成的,并且返回给你。和动态代理的实现是一个事情。
缺点
- 第一点很好理解,既然没有公有或者受保护的构造器,那就意味着他不能被子类化(不能继承其他类)。
- 比较难以阅读,对于不了解接口的程序员来说很难弄清楚,接口实例化对象的过程。