2016-04-23 88 views
5

我正在嘗試使用java類BitSet作爲定製類的字段。我希望班級使用所有位設置的默認位集。對象方法調用可以與對象實例化同時完成嗎?

import java.util.BitSet; 

public class MyClass { 
    private BitSet mask; 

    public MyClass() { 
     this(new BitSet(4)); 
     // want to set all bits first 
     // something like 
     // this(new BitSet(4).set(0,3)); 
    } 

    public MyClass(BitSet mask) { 
     this.mask = mask; 
    }  
} 

默認情況下BitSet構造函數取消所有位。所以在我作爲一個匿名對象發送之前,我想要調用set(int, int)方法來設置所有位。我知道我可以簡單地將字段mask初始化爲新的BitSet,然後從那裏調用set(int, int)方法。

但是,通常我想知道是否有可能在對象實例化時訪問實例方法?

回答

3

爲什麼不寫一個允許BitSet初始化的獨立構造函數?使用Java 8,這可能看起來是這樣的:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(new BitSet(4),(m)->m.set(0,3)); 
    } 
    public MyClass(BitSet mask,Consumer<BitSet> initializer) { 
    initializer.accept(mask); 
    this.mask = mask; 
    } 
} 

你甚至可以做出更通用的引入類型參數的靜態方法:

public static <T> T initialize(T t,Consumer<T> initializer) { 
    initializer.accept(t); 
    return t; 
} 

在這種情況下,較早MyClass會如下所示:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(initialize(new BitSet(4),(m)->m.set(0,3))); 
    } 
    public MyClass(BitSet mask) { 
    this.mask = mask; 
    } 
} 

UPDATE

還有是一種多方式,而不引入新的方法或構造函數:

public class MyClass { 
    private BitSet mask; 
    public MyClass() { 
    this(new BitSet(4) {{ set(0,3); }}); 
    } 
    public MyClass(BitSet mask) { 
    this.mask = mask; 
    } 
} 

anonymous class正在延伸BitSet並添加instance initialization block,因此double curly braces實例化。

+0

我非常虛弱的泛型。但以上是我正在尋找的。它很簡潔,還允許我使用'this'運算符。然後我可以在非默認構造函數中使用通用初始化代碼。謝謝! –

+0

您添加的第三個選項。這種方法的術語是什麼,如果有的話? –

+0

它是一個'實例初始化塊',但由於它出現在匿名類的主體中,它看起來好像是一些特殊的語法(不是)。出於這個原因,人們通常將其稱爲['雙大括號'成語](http://stackoverflow.com/questions/1958636/what-is-double-brace-initialization-in-java)。它經常在[反模式](https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/)中對嵌套的集合初始化進行描述。但是,這裏介紹的方式應該沒問題。 – YoYo

0

否;這將不得不作爲一個單獨的調用來完成,在對象的構建完成後將執行。做一行在您的情況,唯一的方法是,如果方法的返回類型已經BitSet和方法已經回到它被調用的情況下,在這種情況下,你可以做

this(new BitSet(4).set(0, 1)); // Doesn't actually work 

不幸的是,set()void,所以你不能這樣做。

2

BitSet沒有流暢的界面,所以像new BitSet(4).set(0,3)這樣的東西不適用於BitSets。只有靜態的BitSet.valueOf()方法,但這些方法使用起來有些尷尬。但是,如果你想要一個靜態配置,你可以實例化一個具有所需值的BitSet,使用BitSet.toLongArray(),打印數組值並用它實例化你的BitSet。在您的具體的例子默認構造函數可以是:

public MyClass() { 
    this(BitSet.valueOf(new long[]{7})); 
} 

至於問題的通用部分:它只會工作,如果你有一個「二傳手」,返回當前對象,這將讓您鏈調用。因此,對於你自己的類,你可以做這樣的事情:

public class A { 
    private int num; 

    public int getNum() { 
     return num; 
    } 
    public void setNum(int num) { 
     this.num = num; 
    } 
    public A withNum(int num) { 
     setNum(num); 
     return this; 
    } 
} 

如果您使用的是在像位集構造函數,你可以做this(new A().withNum(4));

流利的接口是相當受歡迎(例如AWS SDK有到處都是),只是JDK對象通常沒有它們。

相關問題