Javaメソッドでフラグを使用するベストプラクティス
質問
Javaメソッドでフラグを指定するためのベストプラクティスは何ですか?
ビットフィールドとしてintを使ってSWTを見た:
(部分的には「有効なJava、第2編」からの例。ページ159):
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 1
public static final int STYLE_ITALIC = 1 << 1; // 2
void printText(String text, int flags) {
}
}
.
とあなたのクライアントコールは次のようになります。
printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
.
。しかし、これは、コンパイラチェックなしで異なるクラスからフラグ(INT値)を混在させることができます。
同じ本(「有効なJava」)では、enumsetの使用を見ますが、ユーザーコールは次のようになります。
printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
.
これは少し冗長であり、私はSWTの優雅さを好む。
解決
あなたは壁を襲ったと思います。他のオプションは見られません。Javaは冗長ですが事実です。このような状況では、通常、コードを読みやすくするためにローカル変数を追加します。これを行うことができます、
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
. 他のヒント
ビットスタイルのフラグを希望する場合、JavaはBitSet
でそれらをラップします。それは老人のために周り、それでもそれを使うのを邪魔する人々はほとんどありませんでした(intsでcスタイルのビット処理を好む)。
数常に選択された静的intと結合された、1パスで複数のビットをチェックして設定することを始めるまで、それはかなりうまくいきます。
EnumSet
アプローチで行くことをお勧めします。
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
.
このアプローチはより良いタイプの安全性を提供し、列挙体であるStyle
は完全な吹きoo能力を持ちます。
これに渡って来る人のための遅い答え。これはメモリを減らすためにそれをする1つの方法があり、APIのような素晴らしいenumを持っています:
public static class MyFlag {
public static final MyFlag A = new MyFlag(1<<0);
public static final MyFlag B = new MyFlag(1<<1);
public static final MyFlag C = new MyFlag(1<<2);
public static final MyFlag ALL = A.and(B).and(C);
private final int flag;
private MyFlag(int flag){
this.flag = flag;
}
public MyFlag and(MyFlag limit){
return new MyFlag(flag & limit.flag);
}
public MyFlag not(MyFlag limit){
return new MyFlag(flag | ~limit.flag);
}
public boolean isSet(MyFlag limit){
if(limit ==null){
return false;
}
return (this.flag & limit.flag) != 0;
}
}
.
方法:
public void doFoo(MyFlag flag){
if(MyFlag.A.isSet(flag)){
....
}
if(MyFlag.C.isSet(flag)){
....
}
}
.
呼び出し:
x.doFoo(MyFlag.A.and(MyFlag.C));
. スタイルのセットを取っている限られたメソッドだけがある場合(printText
のような例では)、署名が変わって変数のスタイルのパラメータを取ることができます。
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
.
そしてあなたの電話はuntyped(int)フラグルートに非常に近い:
printText("hello", Style.BOLD, Style.ITALIC);
.
悲しいことに、EnumSet.of(E... )
だけ、EnumSet.of(E first, E... more)
ファクトリはありません。はリーダー=)に運動したままにしておきます。