83

インターフェイスが 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() {
                       ^
4

3 に答える 3

20

これは Java 8 でのみ可能です。Java 7言語仕様 §9.4では、明示的に次のように述べています。

静的メソッドは抽象化できないため、インターフェイスで宣言されたメソッドが静的であると宣言されると、コンパイル時エラーになります。

そのため、Java 7 では、インターフェースの静的メソッドは存在できません。

Java 8 Language Specification §9.4.3に行くと、次のように書かれていることがわかります。

静的メソッドには、メソッドの実装を提供するブロック本体もあります。

そのため、Java 8 ではそれらが存在できると明示的に述べています。

Java 1.7.0_45 で正確なコードを実行しようとしましたが、「modifier static not allowed here」というエラーが表示されました。


以下は、Java 8チュートリアルのDefault Methods (Learning the Java Language > Interfaces and Inheritance)からの直接の引用です。

静的メソッド

デフォルトのメソッドに加えて、インターフェイスで静的メソッドを定義できます。(静的メソッドは、任意のオブジェクトではなく、それが定義されているクラスに関連付けられているメソッドです。クラスのすべてのインスタンスは、その静的メソッドを共有します。)これにより、ライブラリ内のヘルパー メソッドを整理しやすくなります。別のクラスではなく、同じインターフェイス内のインターフェイスに固有の静的メソッドを保持できます。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

于 2014-03-28T13:24:28.633 に答える
15

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();
    }   
}

したがって、インターフェイス内にカプセル化されたデフォルトの実装。

于 2014-03-28T19:05:54.203 に答える