クラスの注意すべき問題を列挙する

3228 ワード

public enum PayMode{

    POS(1, "POS  "),
    ONLINE_PAY(2, "    "),
    BALANCE_PAY(3, "      "),
    OTHER(4, "    ");

    private int code;

    private String value;

    private static Map payModeType = new ConcurrentHashMap();

    static {
        for (PayMode payMode : PayMode.values()) {
            payModeType.put(payMode.getCode(), payMode);
        }
    }

    PayMode(int code, String value) {
        this.code = code;
        this.value = value;
    }

    public static PayMode getPayMode(int payModeCode) {
        return payModeType.get(payModeCode);
    }


}

上記のコードを見たとき、まず静的メソッドgetPayModeがcodeに基づいて列挙クラスインスタンスを取得できるかどうかを考えました.
クラスのロード順序は、静的ブロック、静的メソッド、後にコンストラクタをロードすることが知られていますが、debugでは、クラスを列挙するコンストラクタが静的部分よりも先に実行されることがわかります.これはなぜですか.
次のように解釈されます.
すべての列挙値はpublic static finalですが、なぜそう言うのか、次のコードを見てください.
public enum Day {
    MONDAY("   "),
    TUESDAY("   "),
    WEDNESDAY("   "),
    THURSDAY("   "),
    FRIDAY("   "),
    SATURDAY("   "),
    SUNDAY("   ");

    /**
     *     
     */
    private String desc;

    public String getDesc() {
        return desc;
    }

    /**
     *       ,       
     * @param desc
     */
    private Day(String desc) {
        this.desc = desc;
    }

}

逆コンパイルの結果を見てみましょう
Compiled from "Day.java"
public final class Day extends java.lang.Enum {
  public static final Day MONDAY;
  public static final Day TUESDAY;
  public static final Day WEDNESDAY;
  public static final Day THURSDAY;
  public static final Day FRIDAY;
  public static final Day SATURDAY;
  public static final Day SUNDAY;
  private java.lang.String desc;
  private static final Day[] $VALUES;
  public static Day[] values();
  public static Day valueOf(java.lang.String);
  public java.lang.String getDesc();
  private Day(java.lang.String);
  static {};
}

 
分かりましたか.実は列挙クラスのインスタンスはpublic static finalで、暗黙的な表現にすぎません.では、上記の最初の問題を解決しました.なぜgetPayModeが列挙クラスのインスタンスを手に入れることができますか.
静的メンバーのロード順はコード順にロードされているというもう一つの問題が考えられますが、getPayModeメソッド、またはprivate static MappayModeType=new ConcurrentHashMap()を一番上に置くとロードできないのではないでしょうか.
good question、あなたがこのようにした後、コンパイルはあなたがコンパイルできないことに気づき、コンパイラはあなたに間違いを報告しました.
答えは、列挙クラスのすべてのインスタンス(列挙値)を列挙クラスの最初の行に明示的にリストする必要があります.そうしないと、この列挙クラスはインスタンスを生成することはできません.これは強制的です.
だからあなたは列挙クラスを使うだけで、実例は実はすでにあなたのためにロードして、あなたは持ってきて使うだけでokです!
 
列挙類の解釈については、他の人が書いたものを引用し、
列挙クラスコンストラクタはprivateアクセス修飾子しか使用できないため、外部からコンストラクタを呼び出すことができず、コンストラクタは列挙値を構築するときにのみ呼び出される.enumで定義された列挙クラスはjavaをデフォルトで継承する.lang.Enumクラス、javaを実現しました.lang.Seriablizableとjava.lang.Comparableの2つのインタフェース;すべての列挙値はpublic static finalであり、抽象的でない列挙クラスは子クラスを派遣することはできない.列挙クラスのすべてのインスタンス(列挙値)は、列挙クラスの最初の行に明示的にリストする必要があります.そうしないと、この列挙クラスはインスタンスを生成できません.これらのインスタンス(列挙値)をリストすると、プログラマが明示的に追加することなくpublic static final修飾が自動的に追加されます.
 
ref:
https://www.cnblogs.com/theRhyme/p/10192330.html
https://blog.csdn.net/weixin_34303897/article/details/87163915