代码之家  ›  专栏  ›  技术社区  ›  jb.

JAVA中保持大型静态类型字典的优雅方法——或避免代码过大

  •  0
  • jb.  · 技术社区  · 15 年前

    基本上,我想有一些字典是对遗产的弃权 #define 指令。

    我有一个旧的头文件,包含6000多个定义,用作标志参数some函数,这些定义表示一种实体类型 parameter .

    在C我有

      GetParameter(... , T_CTITLE, ...); 
    

    在Java中我想打电话

      Connector.getParameter(Parameter.CTITLE, ...); 
    

    参数将封装所有与从库中获取参数相关联的逻辑。

    参数实例是从标题自动提取并转换成Java代码的,但问题是参数类太大了,也就是说,我得到了。 code too large 编译错误(让我在下面划线:有6000多个参数)。

    我很高兴能以一种能让IDE使用自动完成的方式来做这个抽象,而且我也非常不喜欢将参数对象存储在say中的想法。 HashMap .

    编辑:参数类的定义方式如下:

    public Parameter{
        /** logic **/
        public static final Parameter<T> parameter1 = new Parameter<T>("NAME", "T", 0xAAB);
        ...
        public static final Parameter<T> parameter6000 = new Parameter<T>("FOO", "T", 0xZZZ);
    }
    
    5 回复  |  直到 15 年前
        1
  •  4
  •   Tom Hawtin - tackline    15 年前

    一个明显的方法是要么划分成一个大的继承链,要么更好地划分成接口(不需要 public static final 噪声)和一个接口来继承它们。

    您可以通过缩小创建代码来节省空间。而不是:

    new Parameter<T>("NAME", "T", 0xAAB)
    

    最低限度的方法是:

    parameter("NAME T AAB")
    

    有关限制的详细信息,请参阅 section 4.10 JVM规范(第二版)。要查看编译后的代码是什么样的,请使用 javap -c .

        2
  •  1
  •   MBCook    15 年前

    也许我不明白你想正确地做什么,但对我来说,这似乎是枚举的完美用法。由于您可以向EnnS添加功能,只要您的Java版本足够近(1.5 +),它们就应该能够做您想做的事情。他们也连载!

    是的,它可以自动完成,尽管6000个列表很大。

    我不知道枚举的大小是否有限制,但您可以找到。

    前任:

    public enum Parameter {
        NAME("Pending", "T", 0xAAB), FOO("Foo", "T", 0x1FC);
    
        private final String displayValue;
        private final char myChar;
        private final int someNum;
    
        private Parameter(String display, char c, int num) {
            this.displayValue = display;
            this.myChar = c;
            this.someNum = num;
        }
    
        public String getDisplayValue() {
            return displayValue;
        }
    
        public char getMyChar() {
            return myChar;
        }
    
        public int getSomeNum() {
            return someNum;
        }
    }
    

    现在你可以做你想做的事情了。前任:

    System.out.println("Hi, the value is " + Parameter.NAME.getSomeNum());
    

    因为它们在运行时不会改变(毕竟,defines can't),枚举应该适合这个账单。

    至于纯大小,您应该尝试稍微对它们进行分类,并将它们放在几个枚举组中。

    这使您能够关联元数据(数字),自动完成,==,等等。

        3
  •  1
  •   Daniel Martin    15 年前

    基本上,我认为多接口方法是可行的。下面是我如何构造这个解决方案;我不知道参数构造函数的第二个参数是什么意思,所以我忽略了它。

    在…/com/yourcompany/legacydefines/parameter.java中:

    package com.yourcompany.legacydefines;
    
    public class Parameter<T> {
      private final String name;
      private final T val;
    
      private Parameter(String name, T val) {
        this.val = val;
        this.name = name;
      }
    
      public static <T> Parameter<T> newParameter(String name, T val) {
        return new Parameter<T>(name, val);
      }
    
      // then, standard getters for "name" and "val"
    }
    

    在…/com/yourcompany/legacydefines/parameters1.java中:

    package com.yourcompany.legacydefines;
    
    import static com.yourcompany.legacydefines.Parameter.newParameter;
    
    interface Parameters1 {
      public static Parameter<String> Parameter0001 = newParameter("ABC", "ABCVAL");
      // ...
      public static Parameter<Integer> Parameter0999 = newParameter("FOO", 0xABCD);
    }
    

    在…/com/yourcompany/legacydefines/parameters2.java中:

    package com.yourcompany.legacydefines;
    
    import static com.yourcompany.legacydefines.Parameter.newParameter;
    
    interface Parameters2 {
      public static Parameter<String> Parameter1001 = newParameter("DEF", "DEFVAL");
      // ...
      public static Parameter<Integer> Parameter1999 = newParameter("BAR", 0x1002);
    }
    

    (等等)

    在…/com/yourcompany/legacydefines/parameters.java中:

    package com.yourcompany.legacydefines;
    
    interface Parameters extends Parameters1, Parameters2, Parameters3, Parameters4,
                                 Parameters5, Parameters6, Parameters7 {}
    

    然后,在其他代码中只使用参数。参数4562

        4
  •  0
  •   Jason S    15 年前

    扩展了TomHawtin的文章,考虑使用JSON对结构进行编码。

    或者更好的是,而不是硬编码Java代码中的参数,将它们放入XML或JSON文件(或属性文件)中,这些文件会被吸入到最终产生的任何JAR文件中。

        5
  •  0
  •   Andreas Dolk    15 年前

    我想这就是你想要的。我想,“t”是类型,您希望使用泛型,这样用户就不必强制转换定义值:

    public class Parameter<T> {
    
        public final static Parameter<String> NAME = new Parameter<String>("hello");
        // .. 5998 more declarations
        public final static Parameter<Integer> FOO = new Parameter<Integer>(0xff0b);
    
    
        private T value;
        private Parameter(T value) {
            this.value = value;
        }
        public T getValue() {
            return value;
        }   
    }
    

    要访问参数,只需调用:

    String value = Parameter.NAME.getValue();
    

    Java常量等于y定义的名称,泛型反映了类型,所以我们只需要将值传递给构造函数。代码完成工作正常:)