11

Java のenum機能によって提供されるシンタックス シュガーは、少し混乱することがあります。コンパイルされない次の例を考えてみましょう。

public enum TestEnum {

    FOO("foo") {
        public void foo() {
            helper();  // <- compiler error
        }
    };

    String name;
    TestEnum(String name) {
        this.name = name;
    }

    public abstract void foo();

    private void helper(){
        // do stuff (using this.name, so must not be static)
    }
}

コンパイラが言う理由を誰でも説明できますか

非静的メソッド 'helper()' は静的コンテキストから参照できません

このコンテキストはどのくらい正確に静的ですか?

への呼び出しを変更するか(ここで 1 つの紛らわしい点があります: コンパイラが示唆するような「静的コンテキスト」に実際にいる場合、" " はどのように機能するのでしょうか?)、または の可視性をデフォルト レベルに上げることによって、このコンパイルを行うことができます。どちらがいいですか?また、より良い質問のタイトルを提案してください:-)this.helper()thishelper()

編集これについていくつかの議論を見つけましたが、本当の答えはありません。this.helper()私の同僚は、それが機能するという事実は、実際にはコンパイラのバグだと考えています。実際、新しい Java バージョンでは動作しないようです(動作しますsuper.helper()が): 「シンボル ヘルパー () が見つかりません」。(奇妙なことが起こっていますが:異なるJavaバージョンで試した後this.helper()、それらのいずれでも再度コンパイルすることはできません...)

4

5 に答える 5

3

このようなことは Java Puzzlers book でカバーされています。IIRC、外部クラスのコンテキストは常にスーパークラスの前に見られます。この場合、ヘルパーが見つかります。しかし、静的コンテキストで値を構築しています (実質的にprivate static finalbeforeがありますFOO)。したがって、エラー。

試してみてくださいsuper.helper();

于 2009-02-24T12:13:15.130 に答える
2

列挙型をクラス構造に変換すると、おおよそ次のようになります。

public abstract class TestEnum {

  public static final TestEnum FOO = new FOO("foo") {
    public void foo() {
        helper();  // <- compiler error
    }
 };

  String name;
  TestEnum(String name) {
      this.name = name;
  }

  public abstract void foo();

  private void helper(){
    // do stuff (using this.name, so must not be static)
  }

}

インスタンス FOO は、TestEnum を拡張する無名クラスです。helper() は非公開であるため、アクセスできないと思われるのはそのためです。したがって、 this.helper() はおそらく機能しないはずです。super.helper() でさえ機能する理由はわかりませんが、 enum が親へのプライベートアクセスを提供する可能性があります。

静的コンテキスト エラーに関しては、エラー メッセージが意味をなさないように思われることに同意します。

于 2009-02-24T14:24:59.587 に答える
1

各列挙型定数は、列挙型クラスのサブクラスの唯一のインスタンスと考えることができます。「通常の」クラスと同様に、列挙「サブクラス」は列挙「スーパークラス」のプライベートメンバーにアクセスできません。(あなたが言及した「これ」の回避策を再現することはできません。)

合理的な解決策は、メソッド アクセスをprivateからprotectedに変更して、列挙定数の「サブクラス」へのアクセスを許可することです。

より良い質問タイトルの提案: 「Java プライベート列挙型メソッド?」または単に「プライベート列挙型メソッド」(JavaタグにJavaらしさを任せます)

于 2009-05-21T03:56:11.157 に答える
0

この問題について言及している記事がありますが、残念ながらドイツ語です。たぶん、まだいくつかの有用な情報を抽出できます。

編集:あなたの問題とは多少異なるようです。私はあなたの例の動作をまだ理解していません。これもここで見られます。

于 2009-02-24T12:04:31.513 に答える