【问题标题】:In Java, how to iterate on the constants of an interface?在 Java 中,如何迭代接口的常量?
【发布时间】:2012-03-30 19:13:41
【问题描述】:

在一个界面中,我以这种方式存储常量(我想知道您对这种做法的看法)。这只是一个虚拟示例。

interface HttpConstants {
    /** 2XX: generally "OK" */
    public static final int HTTP_OK = 200;
    public static final int HTTP_CREATED = 201;
    public static final int HTTP_ACCEPTED = 202;
    public static final int HTTP_NOT_AUTHORITATIVE = 203;
    public static final int HTTP_NO_CONTENT = 204;
    public static final int HTTP_RESET = 205;
    public static final int HTTP_PARTIAL = 206;

        ...
}

有没有一种方法可以遍历此接口中声明的所有常量?

【问题讨论】:

  • 意见:枚举 do 在现代代码中提供了很多好处,强烈推荐。但并非在所有情况下。字符串在很大程度上类似于“标识符”(例如属性名称、属性键、JSF 视图 ID、JPA 命名的查询名称和查询占位符、安全角色……)。问题:字符串文字非常容易输入错误,并且没有编译时检查。我更喜欢将所有此类字符串声明为常量,通常在枚举中。但是,当将它们用作注释参数时,不允许使用枚举,并且仍然需要使用类似于您的代码的public static final Strings。

标签: java


【解决方案1】:

使用反射:

Field[] interfaceFields=HttpConstants.class.getFields();
for(Field f:interfaceFields) {
   //do something
}

但无论如何,如果您可以重新设计您的类,我会建议您处理静态枚举常量构造。因此,假设您的类将始终包含每个常量的 int 值:

enum HttpConstants {

    HTTP_OK(200), HTTP_CREATED(201), HTTP_ACCEPTED(202),
    HTTP_NOT_AUTHORITATIVE(203),HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), HTTP_PARTIAL(206) /* ... */;

    private int value;

    HttpConstants(int aValue) {
        value=aValue;
    }

    public int getValue() {
        return value;
    }
}

然后,循环它:

    for(HttpConstants val: HttpConstants.values()) {
        int value=val.getValue();
            //...
    }

因此,避免了对反射 API 的访问。

【讨论】:

    【解决方案2】:

    我会将这些常量创建为枚举。 Java 中的枚举可以有自己的字段和方法,这对您的情况非常方便。所以我会这样做:

    enum HttpConstant {
        HTTP_OK(200),
        HTTP_CREATED(201),
        HTTP_ACCEPTED(202),
        HTTP_NOT_AUTHORITATIVE(203),
        HTTP_NO_CONTENT(204),
        HTTP_RESET(205),
        HTTP_PARTIAL(206);
    
        private final int id;
    
        HttpConstant(int id) {
            this.id = id;
        }
    
        int getId() {
            return id;
        }
    }
    

    现在迭代很简单:

    for (HttpConstant constant : HttpConstant.values()) {
        //Do something with the constant
    }
    

    这种方式也很容易将一些新值与常量相关联,您只需添加新字段。

    现在你可以使用反射:

    Field[] interfaceFields = HttpConstants.class.getFields();
    for (Field field : interfaceFields) {
        int constant = field.getInt(null);
        //Do something with the field
    }
    

    但是,最好将此方法与枚举一起使用,因为反射编码错误会导致运行时异常而不是编译时错误。

    【讨论】:

      【解决方案3】:
      for(Field f : HttpConstants.class.getFields()){
             int constant = f.getInt(null);
      }
      

      【讨论】:

      • 顺便说一句,这些常量是在 java.net.HttpURLConnection 中定义的
      【解决方案4】:
      public enum HttpConstant {
          /** 2XX: generally "OK" */
          HTTP_OK(200).
          HTTP_CREATED(201),
          HTTP_ACCEPTED(202),
          HTTP_NOT_AUTHORITATIVE(203),
          HTTP_NO_CONTENT(204),
          HTTP_RESET(205),
          HTTP_PARTIAL(206);
      
          private int code;
          private HttpConstant(int code) {
              this.code = code;
          }
      
          public int getCode() {
              return code;
          }
      }
      

      HttpConstant.values().

      【讨论】:

        【解决方案5】:

        通常当我有类似的东西时,我会在界面中创建一个 Map,其中包含键 - 常量名称和值常量 - 值。

        这就是我可以迭代它们的方式。

        【讨论】:

          【解决方案6】:

          我想知道你对这种做法的看法

          考虑使用enum 而不是带有常量的接口。

          enum HttpResultCode {
              HTTP_OK(200),
              HTTP_CREATED(201),
              HTTP_ACCEPTED(202),
              HTTP_NOT_AUTHORITATIVE(203),
              HTTP_NO_CONTENT(204),
              HTTP_RESET(205),
              HTTP_PARTIAL(206);
          
              private final int code;
          
              private HttpResultCode(int code) {
                  this.code = code;
              }
          
              public int getCode(int code) {
                  return code;
              }
          
              public static HttpResultCode forCode(int code) {
                  for (HttpResultCode e : HttpResultCode.values()) {
                      if (e.code == code) {
                          return e;
                      }
                  }
          
                  throw new IllegalArgumentException("Invalid code: " + code);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2010-11-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-09
            相关资源
            最近更新 更多