2.静态工厂方法

什么是静态工厂方法

  1. 在Java中,我们得到类的实例的最常用的方法是使用 new 关键字来调用类的构造方法。
  2. 每使用一个new语句,JVM就会在内存中的堆中开辟一个空间,然后调用构造方法来初始化成员变量,最后把对象的引用返回给调用方。

静态工厂方法的优点

1.静态工厂方法可以有名称。

如果构造器的参数本身没有确切地描述正被返回的对象,那么有适当名称的静态工厂方法会更容易使用,产生的代码也更易于使用。比如,构造函数BigInteger(int,int,Random)返回的BigInteger可能是素数,但如果使用名为BigInteger.probablePrime的静态工厂方法来表示,这样会更加清楚。
一个类只能有一个带有指定方法签名的构造函数,在我们想要避开这个限制的时候,我们提供两个构造函数,他们参数列表只有顺序不同。但这个其实并不是个好方法,因为我们经常会忘记这个参数的顺序,调用了错误的构造函数。但是我们可以通过使用静态工厂方法来解决这个问题,如果一个类需要多个带有相同签名的构造函数时,我们可以用不同名称的静态工厂方法来替代构造函数,仔细地选择名称来突出静态工厂方法的区别。

2.静态工厂方法不是每次调用,都要创建新的对象。

不可变类是指实例不能被修改的类。每个实例中的所有信息都必须在创建时就提供,而且在对象的整个生命周期中还要保持不变。 比如有String,基本类型的包装类,BigInteger,BigDecimal。
我们使用静态工厂方法,可以让这些不可变类使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象。如果程序经常请求创建相同的对象,并且创建对象的代价很高,那么这个技术就可以极大地提高性能。
静态工厂方法能够为重复的调用返回相同对象,这样有助于类总能严格在某个时刻哪些实例应该存在。这样的类叫做实例受控的类(instance-controlled)。

编写实例受控的类有几个原因:

  1. 实例受控使得类可以确保自己是一个单例类(Singleton)或者是不可实例化的。
  2. 使得不可变的类可以确保不会存在两个相等的实例。就是当且仅当a == b时,a.equals(b)才为true。

3.静态方法可以返回原类型的任何子类型的对象,让我们在选择返回对象的类时就有了更大的灵活性。

里氏替换原则中说, 任何基类可以出现的地方,子类一定可以出现。只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
参考别人对这个的解释
构造方法只能返回确切的自身类型,也就是说什么方法的构造函数会返回什么类型的对象,但是静态方法可以灵活的控制返回类型,可以根据需要来返回需要的子类的实例。

Class Person {
    public static Person getInstance(){
        return new Person();
        // 这里可以改为 return new Player() / Cooker()
    }
}
Class Player extends Person{
}
Class Cooker extends Person{
}

比如上面这段代码,Person 类的静态工厂方法可以返回 Person 的实例,也可以根据需要返回它的子类 Player 或者 Cooker。(当然,这只是为了演示,在实际的项目中,一个类是不应该依赖于它的子类的。但如果这里的 getInstance () 方法位于其他的类中,就更具有的实际操作意义了)

4.静态工厂所返回的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值。

举的例子是EnumSet,小于64个元素会返回枚举类型,返回RegularEnumSet实例,用单个long进行支持;有65个或者更多的元素,工厂就返回JumboEnumSet实例,用一个long数组进行支持。

5.静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。


静态工厂方法的缺点

1.类如果不含public或者protected的构造函数,就不能被子类化。

2.静态方法很难被发现。


下面是一些被经常使用的静态工厂方法的名称:

1.from

//from 类型转换
//单个参数,返回这个类型中的一个相对应的实例
Date d = Date.from(instant);

2.of

//of 聚合方法
//多个参数,返回该类型的一个实例,把他们合并起来
Set<Rank> faceCards = EnumSet.of(JACK,QUEEN,KING);

3.valueOf

//valueOf 
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);

4.instance或者getInstance

//instance或者getInstance
//返回的实例是通过方法的参数来描述的
StackWalker luke = StackWalker.getInstance(options);

5.create或者newInstance

//create或者newInstance
//像instance或者getInstance方法一样,但这个方法能够确保每次调用都返回一个新的实例。
Object newArray = Array.newInstance(classObject,arrayLen);

6.getType

//getType Type表示工厂方法返回的对象类型
//像getInstance一样,在工厂方法处于不同的类中的时候使用
FileStore fs = Files.getFileStore(path);

7.newType

//newType Type表示工厂方法返回的对象类型
//像newInstance一样,在工厂方法处于不同的类中的时候使用
BufferedReader br = Files.newBufferedReader(path);

8.type

//type
//getType和newType的简版
List<Complaint> litany = Collections.list(legacyLitany);

静态方法和构造函数都各有用处,要理解各自的长处。不要第一反应就直接调用构造函数,要多加考虑再进行使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335