Javaリフレクション機構の深い理解:シリーズ12 Javaは強固な基盤を築きます

記事のこのシリーズは、GitHubのの「Javaのインタビューガイド」の倉庫に私に手配します、よりエキサイティングなコンテンツが私の倉庫のビューにアクセスしてください

https://github.com/h2pl/Java-Tutorial

そのトラブルのスポットスターカザフスタン下のように

記事は、最初に私の個人ブログに登場しました。

www.how2playlife.com

列挙(列挙)タイプは、それが新たなタイプであり、Java 5つの新機能である定数は、データの特定の部分を表現することを可能にするだけでなく、セキュリティのすべてのタイプの形で表されています。

列挙クラスで

プログラミングでは、時々日曜日に、このような週の月曜日の集合としてデータ要素の限られたセットの数で7つのデータ要素、ジョブからなる赤、黄、緑のコレクションの三色を使用10人の労働者とその上の集合からなるチーム内で、プログラムは、コレクション内の変数の要素の値に制限されます。この場合、これらのデータは、列挙型のセットとして定義することができます。

したがって、列挙型は、このようなセットの週の可能な値に対して週間以内のようなデータ収集の特定のタイプの可能な値は、以下のとおりです。

  {日、月、火、水、木、金、土}

  唯一のコレクションの値をとることができる要素の列挙列挙型定義を持つようコレクションが、週に記載列挙型、この列挙型の7つの要素の合計として定義することができます。列挙型は、データ型を導出しているので、それゆえ、それは列挙型を定義する必要があります、その後、列挙型定義された列挙型の変数を使用します。

 

    enum <枚举类型名> 
      { <枚举元素表> };
      
      其中:关键词enum表示定义的是枚举类型,枚举类型名由标识符组成,而枚举元素表由枚举元素或枚举常量组成。例如: 
      
    enum weekdays 
      { Sun,Mon,Tue,Wed,Thu,Fri,Sat };
      定义了一个名为 weekdays的枚举类型,它包含七个元素:Sun、Mon、Tue、Wed、Thu、Fri、Sat。
      
> 在编译器编译程序时,给枚举类型中的每一个元素指定一个整型常量值(也称为序号值)。若枚举类型定义中没有指定元素的整型常量值,则整型常量值从0开始依次递增,因此,weekdays枚举类型的七个元素Sun、Mon、Tue、Wed、Thu、Fri、Sat对应的整型常量值分别为0、1、2、3、4、5、6。
>   注意:在定义枚举类型时,也可指定元素对应的整型常量值。复制代码
    例如,描述逻辑值集合{TRUE、FALSE}的枚举类型boolean可定义如下:
    enum boolean 
      { TRUE=1 ,FALSE=0 };
    该定义规定:TRUE的值为1,而FALSE的值为0。
      
    而描述颜色集合{red,blue,green,black,white,yellow}的枚举类型colors可定义如下:
    enum colors 
      {red=5,blue=1,green,black,white,yellow};
      该定义规定red为5 ,blue为1,其后元素值从2 开始递增加1。green、black、white、yellow的值依次为2、3、4、5。
      
  此时,整数5将用于表示二种颜色red与yellow。通常两个不同元素取相同的整数值是没有意义的。枚举类型的定义只是定义了一个新的数据类型,只有用枚举类型定义枚举变量才能使用这种数据类型。 复制代码

列挙型クラス - 文法

クラス、同じ位置とのインタフェースとENUM。

あなたは、複数のインターフェースを継承することができます。

あなたは、コンストラクタ、メンバー・メソッド、メンバ変数を持つことができます。

列挙クラスの一般的なカテゴリから1.2異なり

あなたが他の親を継承することはできませんので、デフォルトでは、java.lang.Enumクラスを継承し、java.lang.Serializableとjava.lang.Comparableとのインタフェースを実装java.lang.Enumクラス。

、列挙型の定義を使用して、デフォルトの最終修正を使用するため、サブクラス化することはできません。

デフォルトコンストラクタプライベート修正を使用し、唯一のprivate修飾子を使用します。

クラスのすべてのインスタンスを列挙デフォルトのpublic static final修正を追加し、最初の行に与えられなければならない、または例を生成することはできません。

使用の特定のカテゴリを列挙

このパーツ参照https://blog.csdn.net/qq_27093465/article/details/52180865

定数


    public class 常量 {
    }
    enum Color {
        Red, Green, Blue, Yellow
    }复制代码

スイッチ

JDK1.6のswitch文だけint型、char型、列挙型、列挙型をサポートする前に、私たちのコードを読みやすくします。

    public static void showColor(Color color) {
            switch (color) {
                case Red:
                    System.out.println(color);
                    break;
                case Blue:
                    System.out.println(color);
                    break;
                case Yellow:
                    System.out.println(color);
                    break;
                case Green:
                    System.out.println(color);
                    break;
            }
        }复制代码

列挙に新しいメソッドを追加します。

あなたがあなた自身の方法をカスタマイズする予定がある場合は、最終的に列挙型のインスタンスで直列化されるセミコロンを追加します。要件を定義し、Javaの列挙型のインスタンスにする必要があります。

    enum Color {
        //每个颜色都是枚举类的一个实例,并且构造方法要和枚举类的格式相符合。
        //如果实例后面有其他内容,实例序列结束时要加分号。
        Red("红色", 1), Green("绿色", 2), Blue("蓝色", 3), Yellow("黄色", 4);
        String name;
        int index;
        Color(String name, int index) {
            this.name = name;
            this.index = index;
        }
        public void showAllColors() {
            //values是Color实例的数组,在通过index和name可以获取对应的值。
            for (Color color : Color.values()) {
                System.out.println(color.index + ":" + color.name);
            }
        }
    }复制代码

列挙の方法をカバー

すべての列挙クラスは、列挙クラスから継承し、メソッドをオーバーライドすることができ、そのクラスは、)(被覆方法のtoString例を以下に示します。

    @Override
    public String toString() {
        return this.index + ":" + this.name;
    }复制代码

インターフェイスを実装します

列挙クラスのすべてがjava.lang.Enumから継承します。Javaは多重継承をサポートしていないので、その列挙オブジェクトが他のクラスから継承することはできません。

    enum Color implements Print{
        @Override
        public void print() {
            System.out.println(this.name);
        }
    }复制代码

インターフェイスの組織の列挙を使用します

単純に言えば、列挙を整理するためのインタフェースを実装するために前方に置き、それを分類することです。頻繁に使用する列挙場合は、これを行うと、コードを書く時には、友人を呼び出すことは容易です。

    public class 用接口组织枚举 {
        public static void main(String[] args) {
            Food cf = chineseFood.dumpling;
            Food jf = Food.JapaneseFood.fishpiece;
            for (Food food : chineseFood.values()) {
                System.out.println(food);
            }
            for (Food food : Food.JapaneseFood.values()) {
                System.out.println(food);
            }
        }
    }
    interface Food {
        enum JapaneseFood implements Food {
            suse, fishpiece
        }
    }
    enum chineseFood implements Food {
        dumpling, tofu
    }复制代码

列挙型クラスのコレクション

java.util.EnumSetとjava.util.EnumMapは2つの列挙されています。EnumSetの要素のコレクションが繰り返されないよう、EnumMapの列挙型は、キーであるが、値の任意のタイプであってもよいです。

EnumSetの実装クラスは、JDKに見つからない、ここでEnumMapの例を書き込みます

    public class 枚举类集合 {
        public static void main(String[] args) {
            EnumMap<Color, String> map = new EnumMap<Color, String>(Color.class);
            map.put(Color.Blue, "Blue");
            map.put(Color.Yellow, "Yellow");
            map.put(Color.Red, "Red");
            System.out.println(map.get(Color.Red));
        }
    }复制代码

列挙クラスの使用を注意してください

画像

列挙型オブジェクトの値との比較は、==を必要としない、等しいequalsメソッドヨーヨーを使用するか、値を比較するために直接使用されます。

列挙列挙型クラスは、equalsメソッドをオーバーライドしているので

    /**
     * Returns true if the specified object is equal to this
     * enum constant.
     *
     * @param other the object to be compared for equality with this object.
     * @return  true if the specified object is equal to this
     *          enum constant.
     */
    public final boolean equals(Object other) {
        return this==other;
    }复制代码

原則として列挙クラス

参照のこの部分https://blog.csdn.net/mhmyqn/article/details/48087247

JDK1.5 Javaが列挙をサポートするために始めたことから、それはそれはJavaがジェネリック医薬品のような、新しい機能だけJDK1.5を追加し、列挙として始まっサポートしていない、と言うことです。あなたが最初に通常の機能を提供しない場合は、問題が、下位互換性の問題が発生します、後半の言語発達に追加されました。

Javaの1.5で導入された機能の多くと同様に、下位互換性のために、コンパイラは、私たちは、このような一般的なタイプの消去は、なぜ/ブリッジング方法、foreachの反復、自動ボクシングを生成する理由として、物事の多くを行うためにソースコードを書くのに役立ちます特別な治療コンパイラと呼ばれる一方で、「シンタックスシュガー」と呼ばれる用語を持っているなど、開梱「構文糖液。」だから、ENUM JDK1.5のようにそれが唯一導入されていますが、どのようにそれを達成するために?

抽象Javaクラスjava.lang.Enumは、すべての列挙型の基本クラスであり、1.5に加えました。これは、いくつかの基本的な特性と基本的なメソッドを提供します。また、設定や地図などの列挙はまた、すなわちjava.util.EnumSetとjava.util.EnumMap、サポートを提供しています。

次に、簡単な列挙クラスを定義します

    public enum Day {
        MONDAY {
            @Override
            void say() {
                System.out.println("MONDAY");
            }
        }
        , TUESDAY {
            @Override
            void say() {
                System.out.println("TUESDAY");
            }
        }, FRIDAY("work"){
            @Override
            void say() {
                System.out.println("FRIDAY");
            }
        }, SUNDAY("free"){
            @Override
            void say() {
                System.out.println("SUNDAY");
            }
        };
        String work;
        //没有构造参数时,每个实例可以看做常量。
        //使用构造参数时,每个实例都会变得不一样,可以看做不同的类型,所以编译后会生成实例个数对应的class。
        private Day(String work) {
            this.work = work;
        }
        private Day() {复制代码
        }
        //枚举实例必须实现枚举类中的抽象方法
        abstract void say ();复制代码
    }复制代码

デコンパイル結果

    D:\MyTech\out\production\MyTech\com\javase\枚举类>javap Day.class
    Compiled from "Day.java"复制代码
    public abstract class com.javase.枚举类.Day extends java.lang.Enum<com.javase.枚举类.Day> {
      public static final com.javase.枚举类.Day MONDAY;
      public static final com.javase.枚举类.Day TUESDAY;
      public static final com.javase.枚举类.Day FRIDAY;
      public static final com.javase.枚举类.Day SUNDAY;
      java.lang.String work;
      public static com.javase.枚举类.Day[] values();
      public static com.javase.枚举类.Day valueOf(java.lang.String);
      abstract void say();
      com.javase.枚举类.Day(java.lang.String, int, com.javase.枚举类.Day$1);
      com.javase.枚举类.Day(java.lang.String, int, java.lang.String, com.javase.枚举类.Day$1);
      static {};
    }复制代码

抽象クラスに列挙コンパイラを通過した後、それはjava.lang.Enumを継承する、ことがわかる。列挙し、列挙定数が定義され、対応するのpublic static finalプロパティに、そして、抽象クラスの型にその型は、名前が列挙定数の名前です。

同時に、我々は4つの内部COMの.classファイルクラス/みかん/日の$ 1.classを見ることができ、同じパスOperator.classでCOM /みかん/日の$ 2.class、COM /みかん/日の$ 3.class、COM /二つの方法の値を()とのvalueOf(String)を加えながら;我々はコンストラクタは引数を1つしか持っていた定義が、みかん/日の$ 4.classは、その4つのフィールドが内部クラスを達成するために使用されているにちなんで命名され三つのパラメータとなっている。また、静的ブロックを生成します。次回詳しく見てのこれらの具体的な内容。

バイトコード部分の解析に続いて、ここで:

    InnerClasses:
         static #23; //class com/javase/枚举类/Day$4
         static #18; //class com/javase/枚举类/Day$3
         static #14; //class com/javase/枚举类/Day$2
         static #10; //class com/javase/枚举类/Day$1复制代码

4つのインナークラスは、後で詳細を分析し、4つの内部クラスがあることが分かります。

    static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=5, locals=0, args_size=0
             0: new           #10                 // class com/javase/枚举类/Day$1
             3: dup
             4: ldc           #11                 // String MONDAY
             6: iconst_0
             7: invokespecial #12                 // Method com/javase/枚举类/Day$1."<init>":(Ljava/lang/String;I)V
            10: putstatic     #13                 // Field MONDAY:Lcom/javase/枚举类/Day;
            13: new           #14                 // class com/javase/枚举类/Day$2
            16: dup
            17: ldc           #15                 // String TUESDAY
            19: iconst_1
            20: invokespecial #16                 // Method com/javase/枚举类/Day$2."<init>":(Ljava/lang/String;I)V
            //后面类似,这里省略
    }复制代码

実際には、コンパイラは、次の作業を行うための静的コードブロックを生成する:4つの設定を保存し、コンパイラで生成されたのstatic finalフィールドが静的フィールドの$値を生成し、公開されているすべての列挙列挙型の定義コンパイラによって追加された定数値の方法:

    public static com.javase.Day[] values();  
      flags: ACC_PUBLIC, ACC_STATIC  
      Code:  
        stack=1, locals=0, args_size=0  
           0: getstatic     #2                  // Field $VALUES:[Lcom/javase/Day;  
           3: invokevirtual #3                  // Method "[Lcom/mikan/Day;".clone:()Ljava/lang/Object;  
           6: checkcast     #4                  // class "[Lcom/javase/Day;"  
           9: areturn  
    这个方法是一个公共的静态方法,所以我们可以直接调用该方法(Day.values()),返回这个枚举值的数组,另外,这个方法的实现是,克隆在静态代码块中初始化的$VALUES字段的值,并把类型强转成Day[]类型返回。复制代码

なぜビルド方法は、2つのパラメータを追加しますか?

問題は、明らかに、我々はパラメータだけそれが生成されるのはなぜ三つのパラメータを持つコンストラクタを定義するコンストラクタがありますか?

    从Enum类中我们可以看到,为每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,所以才在构造方法中添加了两个参数。即:复制代码
    另外三个枚举常量生成的内部类基本上差不多,这里就不重复说明了。复制代码

我々は最終的なもので、ほとんどのメソッドは最終的なものである列挙型クラスコード定義された名前と順序属性から参照、特にクローン、readObjectメソッドは、これら3つの方法は、これら3つのメソッドとメダルをのwriteObjectすることができますそれは、静的コードブロックで初期化されるため。

これは単なる一例である、すなわち単一の実施形態、それは効果的なJavaで推奨され、一定の列挙を確実に複製を列挙するために、シリアライゼーションおよびデシリアライゼーションをクローン化することができない列挙型の不変性を保証します単一の実施形態を実現するために列挙を使用しています。

実際の列挙クラス

実際の引数なし

(1)非定義されたパラメータの列挙クラス

enum SeasonType {
    SPRING, SUMMER, AUTUMN, WINTER
}复制代码

(2)実際の使用

// 根据实际情况选择下面的用法即可
SeasonType springType = SeasonType.SPRING;    // 输出 SPRING 
String springString = SeasonType.SPRING.toString();    // 输出 SPRING复制代码

二人は本当の参加を持っています

パラメータの列挙型の(1)のみ定義

enum SeasonType {
    // 通过构造函数传递参数并创建实例
    SPRING("spring"),
    SUMMER("summer"),
    AUTUMN("autumn"),
    WINTER("winter");

    // 定义实例对应的参数
    private String msg;

    // 必写:通过此构造器给枚举值创建实例
    SeasonType(String msg) {
        this.msg = msg;
    }

    // 通过此方法可以获取到对应实例的参数值
    public String getMsg() {
        return msg;
    }
}复制代码

(2)実際の使用

// 当我们为某个实例类赋值的时候可使用如下方式
String msg = SeasonType.SPRING.getMsg();    // 输出 spring复制代码

2つの本当の3つのパラメータがあります。

(1)列挙クラスの定義は、2つのパラメータを有します

public enum Season {
    // 通过构造函数传递参数并创建实例
    SPRING(1, "spring"),
    SUMMER(2, "summer"),
    AUTUMN(3, "autumn"),
    WINTER(4, "winter");

    // 定义实例对应的参数
    private Integer key;
    private String msg;

    // 必写:通过此构造器给枚举值创建实例
    Season(Integer key, String msg) {
        this.key = key;
        this.msg = msg;
    }

    // 很多情况,我们可能从前端拿到的值是枚举类的 key ,然后就可以通过以下静态方法获取到对应枚举值
    public static Season valueofKey(Integer key) {
        for (Season season : Season.values()) {
            if (season.key.equals(key)) {
                return season;
            }
        }
        throw new IllegalArgumentException("No element matches " + key);
    }

    // 通过此方法可以获取到对应实例的 key 值
    public Integer getKey() {
        return key;
    }

    // 通过此方法可以获取到对应实例的 msg 值
    public String getMsg() {
        return msg;
    }
}复制代码

(2)実際の使用

// 输出 key 为 1 的枚举值实例
Season season = Season.valueofKey(1);
// 输出 SPRING 实例对应的 key
Integer key = Season.SPRING.getKey();
// 输出 SPRING 实例对应的 msg
String msg = Season.SPRING.getMsg();复制代码

列挙型クラスの概要

列挙クラスは、概念を理解した後、実際には、列挙は非常に簡単になり、あなたは容易に列挙クラスを書き出すことができます。ので、いくつか本当の小さな例として最初の[OK]を数回練習した後、概念を把握しなければなりません。

重要な概念、私は再び繰り返しでここにいる、最初はパラメータは、あなたが複数のパラメータ、各列挙値を持つことはできませんすることができます列挙値の列挙クラスを覚えて、彼らはこの知識を把握するのに役立つために、古い鉄一つの例です。

それは列挙値は、n個のパラメータは、パラメータ値のコンストラクタを持っている場合、それはパラメータである必要がありますので、それぞれの列挙値は、文のインスタンスを作成するためにコンストラクタを呼び出しますので、必ずn個があることであり、また重要今、このことを理解し、そして私達はちょうどnパラメータを配置する必要がn個の変数のメンバーとして定義され、その後、列挙クラスに対応するget()メソッドを提供され、その後、一例で、インスタンスを取得して自由にすることができ、対応します任意のパラメータの値。

あなたが使いやすいのより多くの列挙クラスをしたい場合は、実際の戦闘IIIのように私の文章を真似することができ、このような重要なパラメータなどの特定のパラメータ値によって、そして、それらに対応する列挙値に何をしたいの値を取得することができます、あなただけの罰金値ものを手に入れます。

列挙API

次のように私たちは、java.lang.Enumクラス継承される列挙定義された列挙クラスを使用し、それはそのAPI、一般的に使用されるAPIを継承します。

  • 文字列名()

名前の列挙を取得します。

  • int型の序数()

列挙取得位置(添字初期値は0です)

  • valueOf(String型のMSG)

対応する列挙型msgで取得。(そのような限り、この方法の使用を適切に使用することができるように、戦闘又は他の二つの列挙クラスの列挙クラスのように)

  • 値()

(例えば、実際にIIIにそれを使用する)、すべての列挙クラスの列挙値を取得します

概要

それは、自然に関する一般的な列挙クラスによって達成されるが、コンパイラは、私たちのために処理されています。すべての列挙型は、java.lang.Enumから継承し、自動的に値とvalueOfメソッドを追加します。

各enum定数は、一定のstaticフィールドで、内部クラスを使用し、内部クラスは、列挙型クラスを継承しています。すべての列挙定数が初期化クラスのロード時に、即ち、静的ブロックによって初期化されます

さらに、適切な例外を達成しながら、これらの三つの方法は、最終のように定義のwriteObjectクローン、readObjectメソッドによってスローされます。これは、各列挙型と列挙型の定数は不変であることを保証します。シングルトンは、スレッドセーフ達成するためにこれらの二つの特徴を列挙するために使用することができます。

参考記事

https://blog.csdn.net/qq_34988624/article/details/86592229https://www.meiwen.com.cn/subject/slhvhqtx.htmlhttps://blog.csdn.net/qq_34988624/article/details/86592229https: //segmentfault.com/a/1190000012220863https://my.oschina.net/wuxinshui/blog/1511484https://blog.csdn.net/hukailee/article/details/81107412

マイクロチャンネル公衆数

Javaテクノロジの川や湖

SSM、SpringBoot:あなたは私のリアルタイム更新記事とドライの共有に注力したい場合は、川や湖の私の公共の数に焦点を当てることができます] [Javaの技術のJava、テクニカルエンジニアアリステーション、著者黄斜めには、Javaの関連技術に焦点を当てMySQL、分散、ミドルウェア、クラスタ、Linuxでは、ネットワーク、マルチスレッド、時には完全なJavaスタックの開発に取り組ん学習経験を共有するポイントドッカー、ELKだけでなく、ドライ商品や技術を話します!

Javaのエンジニアは、学習リソースを必要と:一部のJavaエンジニアの一般的な学習リソースを、世間の注目の数は、背景がキーワードの返信の「Java」何のルーチンを無料で入手することがありません。

私の公共の番号

個人公開番号:黄斜め

学び続ける、SpringBoot、MySQLの、分散、ミドルウェア、サービス、だけでなく、投資銀行業務のポイントを理解し、時折話すポイントアルゴリズムとコンピュータの理論的根拠:著者はマスター985、JAVAのバックエンドテクノロジ・スタックに特化したアリゴールドのドレスJAVAエンジニアであり、書き込みは、生涯学習の力を信じて!

プログラマ3T技術学習リソース:リソースまくる技術を学ぶいくつかのプログラマは、世間の注目の数は、背景がキーワード返信「データ」は何のルーチンを無料で入手することはできません。

おすすめ

転載: juejin.im/post/5d9aedb2518825095879e62b