有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

swt在Java方法中使用标志的最佳实践

在Java方法中指定标志的最佳实践是什么

我见过SWT使用int作为位字段,如:

(示例部分摘自“有效Java,第二版”,第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的优雅

还有其他选择吗?或者这基本上就是你必须选择的两种口味吗


共 (5) 个答案

  1. # 1 楼答案

    如果将采用一组样式的方法的数量有限(如printText,在您的示例中),则可以调整它们的签名以采用数量可变的样式参数:

    void printText(String text, Style... flags) {
      EnumSet<Style> style = logicalOr(flags); // see comment below
      ...
     }
    

    然后您的呼叫非常接近非类型(int)标志路由:

    printText("hello", Style.BOLD, Style.ITALIC);
    

    遗憾的是,没有EnumSet.of(E... )工厂,只有EnumSet.of(E first, E... more),因此您需要一个通用的logicalOr方法来将数组拆分为first+rest块留给读者作为练习=)

  2. # 2 楼答案

    我建议你采用EnumSet方法

    EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
    

    这种方法提供了更好的类型安全性,并且Style作为枚举将具有全面的OO功能

  3. # 3 楼答案

    我猜你撞到墙了。我看不到任何其他选择。Java是冗长的,这是事实。在这种情况下,我通常会添加一个局部变量,以使代码更具可读性。你可以这样做

    EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
    printText("hello", styles);
    
  4. # 4 楼答案

    任何遇到这个问题的人都不能及时回答。这里有一种方法可以减少内存并使用类似枚举的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));
    
  5. # 5 楼答案

    如果需要位样式标志,Java将它们包装在BitSet中。它已经存在很久了,但很少有人愿意使用它(更喜欢在int中嵌入C风格的位处理)

    The api for BitSet can be found here

    再加上一些精心选择的静态int,它的性能相当不错,直到您开始在一次过程中检查和设置多个位为止