48

私がこのようなものを書き込もうとしたとき:

public interface MyInterface {
    static {
        System.out.println("Hello!");
    }
}

コンパイラはそれをコンパイルできませんでした。

しかし、私がこのようなことを書いたとき:

interface MyInterface {
    Integer iconst = Integer.valueOf(1);
}

それを逆コンパイルすると、静的な初期化が見られました:

public interface MyInterface{
    public static final java.lang.Integer i;

    static {};
      Code:
      0:   iconst_1
      1:   invokestatic    #1; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      4:   putstatic       #2; //Field i:Ljava/lang/Integer;
      7:   return
}

この振る舞いを説明していただけますか?

4

5 に答える 5

23

静的初期化はできますが、静的ブロックはできません。静的初期化には、実装する静的コード ブロックが必要であるという事実により、Java 構文が変更されます。

要点は、(Java 8 より前の) インターフェースにコードを含めることを意図したものではありませんが、フィールドを初期化することは許可されているということです。

ところで、ネストされたクラスまたは列挙型を好きなだけコードを持つことができ、フィールドの初期化中にこれを呼び出すことができます。;)

于 2013-11-01T08:07:24.397 に答える
-2

インターフェイスで静的メソッドを宣言する意味はありません。通常の呼び出し MyInterface.staticMethod() では実行できません。(編集: 最後の文が一部の人々を混乱させたため、MyClass.staticMethod() を呼び出すと、MyClass で staticMethod の実装が正確に実行されます。MyClass がインターフェイスである場合、これは存在できません!) 実装クラス MyImplementor.staticMethod() を指定してそれらを呼び出す場合次に、実際のクラスを知っている必要があるため、インターフェイスにそれが含まれているかどうかは関係ありません。

さらに重要なことに、静的メソッドは決してオーバーライドされません。

MyInterface var = new MyImplementingClass();
var.staticMethod();

static の規則では、var の宣言された型で定義されたメソッドを実行する必要があるとされています。これはインターフェイスなので、これは不可能です。

もちろん、静的キーワードはいつでもメソッドから削除できます。すべてがうまくいきます。インスタンス メソッドから呼び出された場合、いくつかの警告を抑制する必要がある場合があります。

以下のコメントのいくつかに答えるために、「result=MyInterface.staticMethod()」を実行できない理由は、MyInterface で定義されたメソッドのバージョンを実行する必要があるためです。ただし、MyInterface はインターフェイスであるため、バージョンを定義することはできません。定義上、コードはありません。

于 2013-11-01T08:39:01.383 に答える