题
在 Java 方法中指定标志的最佳实践是什么?
我见过 SWT 使用 int 作为位域,例如:
(示例部分来自“Effective 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 值)混合在一起,而无需任何编译器检查。
在同一本书(“Effective 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
. 。它已经存在很长时间了,但很少有人费心去使用它(更喜欢在整数中嵌入 C 风格的位处理)。
再加上一些精心挑选的静态整数,它的表现相当不错,直到您开始在一次传递中检查和设置多个位。
我建议你去 EnumSet
方法。
EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
这种方法提供了更好的类型安全性,并且 Style
作为一个枚举将具有成熟的面向对象功能。
迟到的答案,任何人都会过来。这是一种方法来减少内存,并且有一个很好的枚举,如API:
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));
. 如果您只有有限数量的方法,该方法将采用一组样式(如属世代odicetagcode,例如在您的示例中),您可以调整其签名以采取可变的样式参数:
void printText(String text, Style... flags) {
EnumSet<Style> style = logicalOr(flags); // see comment below
...
}
.
然后您的呼叫非常靠近Untyped(int)标志路线:
printText("hello", Style.BOLD, Style.ITALIC);
.
遗憾的是,没有世代odicetagcode工厂,只是生成的世代icetagcode,所以你需要一个通用的世代printText
方法来将你的数组拆分成第一个+休息块。左作为读者练习=)。 不隶属于 StackOverflow