16

enum Animals { DOG, FISH, GOAT };Javaで考えてみましょう。

これで、typeの変数はAnimals、このタイプのメンバーオブジェクトを指すことができます。

Animals a1 = Animals.DOG;それはいいです。

しかし、次のチェーン参照はどのように意味がありますか?

Animals a2 = a1.DOG.FISH.GOAT;(ええ、クレイジーに見えます、これをトリッキーなJavaの質問で見ました)

a1 本当に何を指しているのですか?enumそして、そこから他のメンバーをどのように参照していますか?

例:

public class EnumTest {
    enum Animals { DOG, FISH, GOAT };

    public void test(){
        Animals a1 = Animals.DOG;
        Animals a2 = a1.DOG.FISH.GOAT; //--Strange but valid--
    }
}
4

4 に答える 4

12

Javaの のメンバーはenum、クラスの静的フィールドに似ているため、a1.DOG単に と同じAnimals.DOGです。

public class EnumTest {
    enum Animals { DOG, FISH, GOAT };

    public void test(){
        Animals a1 = Animals.DOG;
        Animals a2 = a1.DOG; // the same as Animals.DOG, but makes code messy
        Animals a3 = a1.DOG.FISH; // WTF chaining???
    }
}

これはenums だけでなくclasses でも​​発生します。

public class A {
    public static A a_1;
    public static A a_2;

    public void boo() {
        A a = A.a_1;
        A b = a.a_1; // That makes a equal to b!
        A c = a.a_1.a_2; // I HATE "CHAINING" LIKE THIS
    }
}

@lichengwuが回答で指摘したように、enumsは最終的に静的フィールドを持つクラスにコンパイルされるため、これはsの問題ではなく、 esenumの問題に似ています。class

他の一部の言語 (C# など) では、型のインスタンスを介して型の静的メンバーを参照することはできませんが、Java は例外です。

タイプのインスタンスを介してタイプの静的メンバーを参照する私見は、悪い習慣です。ご指摘のように混乱を招きます。


Eclipse IDE を使用したい場合は、単純に警告が表示されます。

静的フィールド Animals.DOG は、静的な方法でアクセスする必要があります

Eclipse は、いくつかの提案も提供します。そのうちの 1 つは型を使用してメンバーを参照するように変更することenumであり、もう 1 つは「フィールドの静的修飾子」を削除することです (ただし、実際にはenums では機能しません)。

添加:

Enumeration がコンパイルされるものの内部構造:

final class Animals extends java.lang.Enum<Animals> {
  public static final Animals DOG;
  public static final Animals FISH;
  public static final Animals GOAT;
  public static Animals[] values();
  public static Animals valueOf(java.lang.String);
  static {};
}
于 2012-12-23T14:55:22.520 に答える
5

逆コンパイルAnimals.class

javap Animals.class:

final class Animals extends java.lang.Enum<Animals> {
  public static final Animals DOG;
  public static final Animals FISH;
  public static final Animals GOAT;
  public static Animals[] values();
  public static Animals valueOf(java.lang.String);
  static {};
}

すべての型は Animals のインスタンスなので、他の型を参照できます。

于 2012-12-23T14:47:11.503 に答える
2

あなたが実証したことは、Javaが列挙型を処理する方法の結果です。Animals列挙型定数は静的参照であり、C のような数値プリミティブではありません。オブジェクト/インスタンス参照 ( ) を介して型 (この場合は ) の静的メンバーにアクセスできるAnimals.DOGため、任意の列挙型定数から常に他の列挙型定数にアクセスできます。 . ここでの秘訣は、静的メンバーがメンバーである型のインスタンスへの参照であることです。

于 2012-12-23T14:42:21.333 に答える
0

enumその要素を this の静的インスタンスとして作成しますenum。場合によっては、これらのインスタンスが this のサブクラスになりますenum

もちろん、オブジェクトを使用してクラス メソッドとクラス インスタンス (つまり、静的) にアクセスできます。

于 2012-12-23T14:44:34.913 に答える