web-dev-qa-db-ja.com

メソッドで列挙型をローカルで宣言できないのはなぜですか?

今日、私はこのようなものをコーディングしていることに気づきました...

public class LocalEnums {

    public LocalEnums() {
    }

    public void foo() {
        enum LocalEnum {
            A,B,C
        };

        // ....
        // class LocalClass { }

    }
}

コンパイラがローカルenumでエラーを報告したとき、私はちょっと驚きました:

メンバー列挙LocalEnumをローカルにすることはできません

enumsclassesのようにローカルで宣言できないのはなぜですか?

これは特定の状況で非常に役立つことがわかりました。私が働いていた場合、残りのコードはenumについて何も知る必要はありませんでした。

これが不可能な理由、またはこれがJavaのfuture機能である理由を説明するstructural/design競合はありますか?

54
bruno conde

列挙型は、静的なネストされたクラスです静的メンバー変数(列挙値)を定義するためです内部クラスでは許可されていませんhttp://docs.Oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1 .

更新:JLSJava言語仕様)を調べていました静的なネストされたクラスの制限に関する詳細、およびそれは見つかりませんでした(おそらくそこにありますが、別のトピックの下に隠されています)。純粋な実装の観点からは、これができなかった理由はありません。だから私はそれが言語哲学の問題だったのではないかと疑っています。それは実行されるべきではないため、サポートされません。しかし、私はそこにいなかったので、それは純粋な推測です。

コメントとして:メソッドが十分に大きく、独自の列挙が必要な場合は、リファクタリングが必要であることを示す強い兆候です。

37
kdgregory

匿名の内部クラスでない限り、メソッド内でtypesを記述することはめったにありません。ただし、ネストされた列挙型を記述することはできます。

public class NestedEnum
{
    private enum MyEnum
    {
        X, Y, Z
    }

    public void foo()
    {
    }
}

read内で新しい型を宣言したメソッド-ネストされた型としてではなく、メソッド内で宣言したい具体的な理由はありますか? ? 「他のメソッドを知る必要はない」という議論を見ることができますが、コメントはそれを整理し、さらに読みやすいコードを残すことができると思います。

15
Jon Skeet
  1. 「ネストされた列挙型は暗黙的に静的です。」 8.9列挙

  2. ネストされた列挙型には、暗黙的に静的アクセス修飾子が含まれていると推測するのが妥当です。

  3. 「ローカルクラス宣言にpublic、protected、private、staticのいずれかのアクセス修飾子が含まれている場合、コンパイル時エラーです。」 14.3 14.3 Local Class Declarations
10
emory

Java内部クラス定義では、コンパイル時定数は静的に宣言でき、Enumのメンバーは明らかにコンパイル時定数であり、enumは静的クラスであると言われているため、奇妙です。 ..

ドキュメント

8.1.3内部クラスと包含インスタンス

(...)コンパイル時の定数フィールドでない限り、内部クラスは静的メンバーを宣言できません。

class Outer{
    class Inner extends HasStatic{
        static final int x = 3;         // ok - compile-time constant
        static int y = 4;           // compile-time error, an inner class
    }
    static class NestedButNotInner{
        static int z = 5;           // ok, not an inner class
    }
    interface NeverInner{}              // interfaces are never inner
}
3
no_ripcord

http://mindprod.com/jgloss/enum.html は、Java enums-前述のように、enumは静的として定義されているため、 tローカルとして宣言される

2
Peter