2016-04-23 12 views
5

JavaクラスBitSetをカスタムクラスのフィールドとして使用しようとしています。そして、私はクラスがすべてのビットが設定されたデフォルトの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の初期化を可能にする別のコンストラクタを作成しないのはなぜですか?うその場合

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

MyClass以前: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 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はしたがってdouble curly bracesBitSetを拡張し、instance initialization blockを添加することによってインスタンス化されています。

+0

私はジェネリック薬が非常に弱いです。しかし、上記はまさに私が探しているものです。簡潔で、 'this'演算子を使用することもできます。次に、私は非デフォルトのコンストラクタで共通の初期化コードを持つことができます。ありがとう! –

+0

追加した3番目のオプション。もしあれば、このアプローチの用語は何ですか? –

+0

これは 'インスタンスイニシャライザブロック'ですが、匿名クラスの本体に表示されるため、特殊な構文(あたかもそうではありません)のように見えます。そのため、人々はしばしばそれを[二重ブレースのイディオム](http://stackoverflow.com/questions/1958636/what-is-double-brace-initialization-in-java)と呼んでいます。ネストされたコレクションの初期化については、[anti-patterns](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 

残念ながら行っている可能性がある場合にはそれが呼び出されたインスタンスを、戻ってきた場合、あなたの状況で1行でそれを行うための唯一の方法は、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})); 
} 

:あなたがチェーンにあなたをできるようになり、現在のオブジェクトを返す「セッター」を、持っている場合にのみ動作しますコール。あなたがたBitSetと同様、コンストラクタであなたがthis(new A().withNum(4));

流暢インターフェイスは、例えばAWS SDKがいることを持っている(かなり人気があります行うことができます使用している場合

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; 
    } 
} 

:だからあなた自身のクラスのためにあなたは、このような何かを行うことができますどこでも)、JDKオブジェクトには通常それらがありません。

関連する問題