1

興味深い要件があります。フォームの大きな列挙型があります

public enum BpcCmsError {

    ERROR_TYPE_1("Error message 1"), 
    ERROR_TYPE_2("Error message 2"),
    ERROR_TYPE_3("Error message 3");


    private int errorCode;
    private final String errorMessage;
    public static final int ERRORCODE_BASE = 100;

数字から始めてカウントアップする一意のエラーコードを割り当てる必要があるため、コンストラクターがあります。

private BpcCmsError(String message) {
        this.errorMessage = message;
 }

と静的ブロック

static {
        int code = ERRORCODE_BASE;
        for (BpcCmsError error : EnumSet.allOf(BpcCmsError.class)) {
            error.errorCode = ++code;
       }
}

これは問題なく動作します。

ただし、理想的には次のように、これらのエラー コードを割り当てる際に柔軟性を追加する必要があります。

    ERROR_TYPE_1("Error message 1"), 
    ERROR_TYPE_2("Error message 2"),
    ERROR_TYPE_3(200,"Error message for code");

これは、引数が 2 つのコンストラクターによって、後続のエラー コードが最初のパラメーターの値から開始されるようにするためです。私の場合、エラー コードは 100、101、200、201 などになります。もちろん、このジャンプが許可されているかどうかを確認する必要があります。たとえば、すでに 200 を超えている可能性があります。Javaで列挙型を使用してこれを達成する方法に関するヒントはありますか?

4

3 に答える 3

4

列挙型が必要なようには感じません...エラーメッセージに対して一連の整数エラーコードをマップしようとしているようです。

その場合、ある種のマップが必要です

したがって、次のようなものがあります(IDEがないため、愚かな構文エラーをお詫びします)

public class BpcCmsError {
    private Map<int, String> errorMap = new HashMap<int, String>();
    private int lastErrorCode = 0;

    public void addError(String message) {
       errorMap.put(lastErrorCode++, message);
    }

     public void addError(int code, String message) {
       errorMap.put(code, message);
       lastErrorCode = code++;
    }

    public String getMessage(int code) {
       return errorMap.get(code);
    }

}
于 2013-06-08T12:09:27.127 に答える
2

明らかな答えは、private static int nextErrorCodeを使用するたびにそれをインクリメントすることです...しかし、列挙型コンストラクターから静的フィールドを参照できないため、これは機能しません(列挙型の静的初期化の一部として呼び出されます)。 . Java 7仕様から:

staticコンストラクター、インスタンス初期化ブロック、またはその型のインスタンス変数初期化式から、定数変数 (§4.12.4) ではない列挙型のフィールドを参照すると、コンパイル時エラーになります。

回避策は、カウンターを単純な静的内部クラスに保持することです。

public enum BpcCmsError {

  ERROR_TYPE_1("Error message 1"),
  ERROR_TYPE_2("Error message 2"),
  ERROR_TYPE_3(200, "Error message 3");

  private final int errorCode;
  private final String errorMessage;

  private BpcCmsError(String message) {
    this.errorMessage = message;
    this.errorCode = NextErrorCode.get();
  }

  private BpcCmsError(int errorCode, String message) {
    this.errorMessage = message;
    this.errorCode = NextErrorCode.get(errorCode);
  }

  private static class NextErrorCode {
    private static int nextErrorCode = 100;

    public static int get() {
      return nextErrorCode++;
    }

    public static int get(int errorCode) {
      if (errorCode < nextErrorCode) {
        throw new IllegalArgumentException("Requested error code " + errorCode + " exceeds next valid error code " + nextErrorCode);
      }
      nextErrorCode = errorCode;
      return nextErrorCode++;
    }
  }
}
于 2013-06-08T12:16:10.857 に答える
1

ブロックで作成したEnumMapエラーコードを保持することをお勧めします。enumstatic

public enum ErrorCode {

    ERROR_TYPE_1("Error message 1"),
    ERROR_TYPE_2("Error message 2"),
    ERROR_TYPE_3(200, "Error message 3"),
    ERROR_TYPE_4("Error message 1"),
    ERROR_TYPE_5(300, "Error message 2"),
    ERROR_TYPE_6("Error message 3");
    private final int errorCode;
    private final String errorMessage;
    private static final Map<ErrorCode, Integer> ERROR_CODES;
    private static final int ERROR_CODE_BASE = 100;

    static {
        ERROR_CODES = new EnumMap<>(ErrorCode.class);
        int code = ERROR_CODE_BASE;
        for (final ErrorCode ec : values()) {
            if (ec.errorCode > 0) {
                if (ec.errorCode <= code) {
                    throw new ExceptionInInitializerError("Non unique code for " + ec);
                }
                code = ec.errorCode;
            }
            ERROR_CODES.put(ec, code++);            
        }
    }

    private ErrorCode(final String errorMessage) {
        this(-1, errorMessage);
    }

    private ErrorCode(final int errorCode, final String errorMessage) {
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public int getErrorCode() {
        return ERROR_CODES.get(this);
    }
}

これは非常に柔軟です。コード生成のロジックを非常に簡単に変更できます。

JavaEnumMapも非常に気の利いたもので、キーMap用に最適化されていenumます。

簡単なテスト:

public static void main(String[] args) throws Exception {
    for(final ErrorCode errorCode : ErrorCode.values()) {
        System.out.println(errorCode + ", code is " + errorCode.getErrorCode());
    }
}

出力:

ERROR_TYPE_1, code is 100
ERROR_TYPE_2, code is 101
ERROR_TYPE_3, code is 200
ERROR_TYPE_4, code is 201
ERROR_TYPE_5, code is 300
ERROR_TYPE_6, code is 301
于 2013-06-08T12:53:07.507 に答える