1. 程式人生 > >Java物件學習之建立物件——使用靜態工廠方法代替構造器缺點

Java物件學習之建立物件——使用靜態工廠方法代替構造器缺點

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。

      靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺點。主要概括如下:

優點:

  • 靜態工廠方法有名稱,可以明確的建立對應功能和屬性的Java物件
  • 靜態工廠方法可以預構建Java物件,實現在必要的情況下建立儘量少的物件例項
  • 靜態工廠方法可以獲取預構建Java物件的任何子類物件
  • 靜態工廠方法在構建引數化例項的時候,程式碼更簡潔

缺點:

  • Java類如果沒有公有的或者受保護的構建器,就不能被子類化
  • 靜態工廠方法和一般靜態方法沒有任何區別

靜態工廠方法與構造器建立Java物件的對比已經介紹完了,靜態就來介紹一下使用靜態工廠方法建立物件的缺點,以及我們常常使用的一些靜態工廠方法的名稱。

 

1,靜態工廠方法建立物件缺點

1.1 類如果不含有公共的或者受保護的構造器,就不能被子類化

這句話與我們上面總結介紹的優點三是相悖的。其實就是這一句話

 

1.2  它們在形式上和普通的靜態方法沒有任何區別

這樣就面臨一個問題,如果一個類提供了靜態方法構建該類的例項物件但是沒有API的話,我們很難找到究竟該如何例項化一個該類的物件。

 

2,常見的用於構建物件的靜態工廠方法名稱

 

(1)valueOf()

這個大家一定不陌生,因為我們平時用的實在是太多了。最常見的就是幾個基本型別封裝起來的類,比如Integer,Float等:

 

static Integer valueOf(int i)
          返回一個表示指定的 int 值的 Integer 例項。
static 
Integer
valueOf(String s)
          返回儲存指定的 String 的值的 Integer 物件。
static Integer valueOf(String s, int radix)
          返回一個 Integer 物件,該物件中儲存了用第二個引數提供的基數進行解析時從指定的 String 中提取的值。

 

static Float valueOf(float f)
          返回表示指定的 float 值的 Float 例項。
static Float valueOf(String s)
          返回儲存用引數字串 s 表示的 float 值的 Float 物件。

 

(2)of(),一種valueOf()簡寫

比如EnumSet:

 

static
<E extends Enum<E>>
EnumSet<E>
of(E e)
          建立一個最初包含指定元素的列舉 set。
static
<E extends Enum<E>>
EnumSet<E>
of(E first, E... rest)
          建立一個最初包含指定元素的列舉 set。
static
<E extends Enum<E>>
EnumSet<E>
of(E e1, E e2)
          建立一個最初包含指定元素的列舉 set。
static
<E extends Enum<E>>
EnumSet<E>
of(E e1, E e2, E e3)
          建立一個最初包含指定元素的列舉 set。
static
<E extends Enum<E>>
EnumSet<E>
of(E e1, E e2, E e3, E e4)
          建立一個最初包含指定元素的列舉 set。
static
<E extends Enum<E>>
EnumSet<E>
of(E e1, E e2, E e3, E e4, E e5)
          建立一個最初包含指定元素的列舉 set。

 

(3)getInstance(),返回的物件通過方法的引數來描述,對於Singleton來說,就沒有引數

(4)newInstance(),和上面一樣,但是它的特點是可以保證每次返回的物件都不同

(5)getType(),和(3)一樣,通常在工廠方法不在本類中的時候使用,Type表示工廠方法鎖返回的物件型別

(6)newType(),和(4)一樣,通常在工廠方法不在本類中的時候使用,Type表示工廠方法鎖返回的物件型別

其中(5)和(6)可以會看我在優點一舉的例子,就是通過這樣的方式獲取的例項。對於(3)和(4)我這裡也可以很快的舉一個例子,可以參考一下。

 

package hfut.com.why;

 public class ConstantStringFactory {

     private String description;
     private int id;

     private static ConstantStringFactory cstr = new ConstantStringFactory("this is a constant string");

     public ConstantStringFactory() {

     }

     public ConstantStringFactory(String str) {
         // TODO Auto-generated constructor stub
         this.description = str;
     }

     public ConstantStringFactory(String str, int id) {
         // TODO Auto-generated constructor stub
         this.description = str;
         this.id = id;
     }

     // 獲取例項--單例模式Singleton,當構造器權威私有的時候
     public static ConstantStringFactory getInstance() {
         return cstr;
     }

     // 依據引數獲取例項1
     public static ConstantStringFactory getInstance(String str) {
         return new ConstantStringFactory(str);
     }

     // 依據引數獲取例項2
     public static ConstantStringFactory getInstance(String str, int id) {
         return new ConstantStringFactory(str, id);
     }

     // 每次建立不同的例項物件
     public static ConstantStringFactory newInstance() {
         return new ConstantStringFactory();
     }

     @Override
     public String toString() {
         // TODO Auto-generated method stub
         return description;
     }

     @Override
     public boolean equals(Object arg0) {
         // TODO Auto-generated method stub
         return this.toString().equals(arg0.toString());
     }

 }