インターフェイスは100%純粋な抽象クラスのようなものであることを知っています。そのため、メソッドを実装することはできません。しかし、奇妙なコードを見ました。誰でも説明できますか?
コードスニペット:
interface Whoa {
public static void doStuff() {
System.out.println("This is not default implementation");
}
}
編集:
私のIDEはIntellij Idea 13.1です。プロジェクトSDKはJava 7 <1.7.0_25>です。 IDEはコンパイラエラーを表示していません。しかし、コマンドラインでコードをコンパイルすると、次のメッセージが表示されます。
Whoa.Java:2: error: modifier static not allowed here public static void doStuff() { ^
Java 8から、デフォルトのメソッドに加えてインターフェースで静的メソッドを定義できます。
静的メソッドは、オブジェクトではなく、定義されているクラスに関連付けられているメソッドです。クラスのすべてのインスタンスは、静的メソッドを共有します。
これにより、ライブラリでヘルパーメソッドを簡単に整理できます。インターフェースに固有の静的メソッドを、別個のクラスではなく同じインターフェースに保持できます。
次の例では、タイムゾーン識別子に対応するZoneId
オブジェクトを取得する静的メソッドを定義しています。指定された識別子に対応するZoneId
オブジェクトがない場合は、システムのデフォルトのタイムゾーンを使用します。 (その結果、メソッドgetZonedDateTime
を簡素化できます)
コードは次のとおりです。
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Java 8のすべての興味深いことについては、 Java 8に関するすべて をお読みください。
これはJava 8でのみ可能です。 Java7Language Specification§9.4 では、明示的に状態:
静的メソッドは抽象化できないため、インターフェイスで宣言されたメソッドが静的に宣言されている場合、コンパイル時エラーです。
そのため、Java 7では、インターフェイスに静的メソッドは存在しません。
Java8Language Specification§9.4. にアクセスすると、次のように表示されます:
静的メソッドには、メソッドの実装を提供するブロック本体もあります。
そのため、Java 8にはcanが存在できることが明示的に示されています。
Java 1.7.0_45で正確なコードを実行しようとしましたが、「modifier static not here here」というエラーが表示されました。
Java8チュートリアルから直接引用しています デフォルトのメソッド(Java言語の学習>インターフェースと継承) :
静的メソッド
デフォルトのメソッドに加えて、インターフェイスで staticメソッド を定義できます。 (静的メソッドは、オブジェクトではなく、定義されたクラスに関連付けられたメソッドです。クラスのすべてのインスタンスは、静的メソッドを共有します。)これにより、ライブラリ内でヘルパーメソッドを整理しやすくなります。インターフェースに固有の静的メソッドを、別個のクラスではなく同じインターフェースに保持できます。次の例では、タイムゾーン識別子に対応する
ZoneId
オブジェクトを取得する静的メソッドを定義しています。指定された識別子に対応するZoneId
オブジェクトがない場合、システムのデフォルトのタイムゾーンが使用されます。 (その結果、メソッドgetZonedDateTime
を単純化できます):public interface TimeClient { // ... static public ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead."); return ZoneId.systemDefault(); } } default public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
クラスの静的メソッドのように、インターフェイスのメソッド定義が静的メソッドであることを指定するには、メソッドシグネチャの先頭に
static
キーワードを使用します。静的メソッドを含む、インターフェイス内のすべてのメソッド宣言は暗黙的にpublic
であるため、public
修飾子を省略できます。
Javaバージョン7以下の場合、同様に機能的には、インターフェース本体内で宣言されたネストされたクラスを使用して実現できます。そして、このネストされたクラスは外部インターフェースを実装します。
interface I1{
public void doSmth();
class DefaultRealizationClass implements I1{
@Override
public void doSmth() {
System.out.println("default realization");
}
}
}
class MyClass implements I1{
@Override
public void doSmth() {
new I1.DefaultRealizationClass().doSmth();
}
}
したがって、インターフェイス内にカプセル化されたデフォルトの実装。