この質問に答えるためにJava言語仕様を検索しているときに、
クラスを初期化する前に、その直接のスーパークラスを初期化する必要がありますが、クラスによって実装されるインターフェースは初期化されません。同様に、インターフェイスのスーパーインターフェイスは、インターフェイスが初期化される前に初期化されません。
私自身の好奇心から、試してみましたが、予想通り、インターフェースInterfaceTypeが初期化されていませんでした。
public class Example {
public static void main(String[] args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}
class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}
class ClassInitializer {
static {
System.out.println("static initializer");
}
}
interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();
public void method();
}
このプログラムは印刷します
implemented method
ただし、インターフェースがdefaultメソッドを宣言する場合は、初期化が行われます。InterfaceType次のように与えられたインターフェースを考えます。
interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();
public default void method() {
System.out.println("default method");
}
}
次に、上記と同じプログラムが印刷されます
static initializer
implemented method
つまり、staticインターフェースのフィールドが初期化され(詳細初期化手順のステップ9)、static初期化されるタイプの初期化子が実行されます。これは、インターフェースが初期化されたことを意味します。
JLSでこれが発生することを示すものは何も見つかりませんでした。誤解しないでください。実装しているクラスがメソッドの実装を提供していない場合にこれが発生することを理解していますが、提供している場合はどうなりますか?この状態はJava言語仕様にありませんか、何か見落としましたか、それとも間違って解釈しますか?
interfaceはJavaでは具体的なメソッドを定義すべきではないと考えました。InterfaceTypeコードがコンパイルされたことに驚きました。
defaultメソッドを使用できます。