【问题标题】:Java boolean options in class configuration类配置中的 Java 布尔选项
【发布时间】:2011-12-19 08:50:58
【问题描述】:

通常必须使用许多布尔选项来配置一个类。在 Java 中有哪些推荐的方式来指定执行配置?

我可以想到 4 种方式如何将选项传递给类。

  1. 使用位掩码。高效,易于使用,但没有组合在一起。在其他成员中通过自动完成更难找到。大小受限。

    public static final int A_ENABLED = 1 << 1;
    public static final int B_ENABLED = 1 << 2;
    
  2. 使用(内部)参数类。难以创建,太冗长。

    public static class Params {
        private final boolean enabledA;
        private final boolean enabledB;
    }
    
    public class MyFunctionality {
        private final SomeOtherArguments myDataArguments;
        ...
        private final Params params;
    
        MyFunctionality(SomeOtherArguments myDataArguments, Params params);
    }
    
  3. 使用布尔字段作为类的一部分。增加类的详细程度(您必须担心的构造函数中的额外参数)。每次参数更改时都必须修改类的构造函数。在 2 选项中,只有 Params 类会改变。

    public class MyFunctionality {
        private final SomeOtherArguments myDataArguments;
        ...
        private final boolean enabledA;
        private final boolean enabledB;
        private final boolean enabledC;
        private final boolean enabledD;
        ...
    
        public MyFunctionality(SomeOtherArguments someOtherArguments, boolean enabledA, boolean enabledB, boolean enabledC, boolean enabledD);
    }
    
  4. 使用枚举。

    public static enum Params {
        OPTION_A, OPTION_B
    }
    

你能想到其他更好的方法吗?

【问题讨论】:

    标签: java class configuration enums options


    【解决方案1】:

    另一种方法是保存一组布尔值。它就像位掩码,但可能更易于阅读和调试。

    无论如何,我建议您将位掩码或设置与枚举结合使用。枚举允许更轻松地管理和控制可能的值。使用valueOf(String) 方法可以轻松实现从配置文件中读取值。

    【讨论】:

    • 中肯的建议。由于现在允许在数字中使用二进制文字和下划线,因此在 Java 7 中 Bitmaks 也可以变得更加清晰。
    • 如果你打算使用枚举,你也可以使用 EnumSet。
    【解决方案2】:

    这个实现怎么样

    class MyFunctionality {
        private boolean [] options;
    
        public static final int OPTION1 = 0;
        public static final int OPTION2 = 1;
        public static final int OPTION3 = 2;
        /*Set the default values*/
        public static final boolean [] defaultValues = new boolean[3];
        static {
            defaultValues[OPTION1] = true;
            defaultValues[OPTION2] = false;
            defaultValues[OPTION3] = true;
        }
    
        MyFunctionality(String something, int somethingelse, boolean [] options) {
            if(options == null) {
                options = defaultValues.clone();
            }
            this.options = options;
    
            for(boolean value : this.options) {
                System.out.println(value);
            }
        }
    
        public static boolean [] getModelOptions() {
            return defaultValues.clone();
        }
    }
    

    实现类

    class MyFunctionImpl {
        public static void main(String [] ars) {
            boolean [] optionsINeedToSet = MyFunctionality.getModelOptions();
            optionsINeedToSet[MyFunctionality.OPTION3] = false;
    
            new MyFunctionality("Try this", 10101, optionsINeedToSet);
            new MyFunctionality("Try this", 10101, null);
        }
    }
    

    【讨论】:

      【解决方案3】:

      枚举和 EnumSet 是专门为此设计的。

      class myClass {
      
        public static enum Options {A,B,C};
      
        private EnumSet optionSet = EnumSet.noneOf(Option.class);
      
        public setOption(Option o) {
          optionSet.add(o);
        }
        public setOptions(EnumSet addset) {
          optionSet.addAll(addset);
        }
      
      }
      

      optionSet 包含“设置”的选项。 EnumSet 非常高效,在大多数实现中每个枚举元素只使用一位,并允许在恒定时间内获取和设置。当然,您也可以将设置选项限制为构建时间。

      编辑:您可以同时设置多个选项,例如 A 和 B:

      myClassInstance.setOptions(EnumSet.of(A,B));
      

      【讨论】:

      • 它看起来确实是一个不错的选择,但使用位掩码看起来更好的一件事是它们不那么冗长。 IE。你可以写在一行 A |乙| C,但你会用 EnumSet 做吗?
      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 2012-07-10
      • 2017-09-02
      • 1970-01-01
      • 2014-11-16
      • 2011-04-13
      • 1970-01-01
      • 2019-05-13
      相关资源
      最近更新 更多