Javaのinterfaceは、何故protected修飾が出来ないのか


何故Javaの`interface`に宣言されているメソッドに`protected`修飾が出来ないようにされたのでしょうか。

* * *

Androidの`onClick`メソッドは`public`でしかオーバーライド出来ません。理由は`interface`は`public`じゃないと宣言できないからです。このようにした理由はなぜでしょうか？

`private`だとアクセスできないのはわかります。  
なら、`package private`や`protected`はなぜ出来ないのでしょうか。継承先ではアクセスできるはずです。




インターフェースは外側から使えるメソッドを定義しておくのが目的なので`public`なメソッドがあれば十分です。  
とは言え、Java 8でデフォルトメソッドが扱えるようになったので、そのデフォルトメソッドから利用するヘルパメソッド等を隠蔽する意義はあるかも知れません。  
実際手元の[JDK9](https://jdk9.java.net/download/)（build
122）の`javac`では以下のコードがコンパイルを通りました。

[code]

    interface Test {
       default void meth() {
        help();
       }
       private void help() {
        System.out.println("Hello!");
       }
    }
    
[/code]

`protected`については多重継承による衝突の解決の問題もあるのではないでしょうか。

以下、参考までにJVMの仕様変更について  
[Java SE 7版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> All interface methods must have their ACC_ABSTRACT and ACC_PUBLIC  
>  flags set; they may have their ACC_VARARGS, ACC_BRIDGE and  
>  ACC_SYNTHETIC flags set and must not have any of the other flags in  
>  Table 4.5 set (JLS §9.4).

従ってJVMのレベルでインターフェースで`private`や`protected`なメソッドは扱えません。

一方[Java SE 8版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> Methods of interfaces may have any of the flags in Table 4.6-A set  
>  except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS  
>  §9.4). In a class file whose version number is less than 52.0, each  
>  method of an interface must have its ACC_PUBLIC and ACC_ABSTRACT flags  
>  set; in a class file whose version number is 52.0 or above, each  
>  method of an interface must have exactly one of its ACC_PUBLIC and  
>  ACC_PRIVATE flags set.

`protected`は相変わらずダメですが`private`は扱えるようになっています。




インターフェースは外側から使えるメソッドを定義しておくのが目的なので`public`なメソッドがあれば十分です。  
とは言え、Java 8でデフォルトメソッドが扱えるようになったので、そのデフォルトメソッドから利用するヘルパメソッド等を隠蔽する意義はあるかも知れません。  
実際手元の[JDK9](https://jdk9.java.net/download/)（build
122）の`javac`では以下のコードがコンパイルを通りました。

[code]

    interface Test {
       default void meth() {
        help();
       }
       private void help() {
        System.out.println("Hello!");
       }
    }
    
[/code]

`protected`については多重継承による衝突の解決の問題もあるのではないでしょうか。

以下、参考までにJVMの仕様変更について  
[Java SE 7版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> All interface methods must have their ACC_ABSTRACT and ACC_PUBLIC  
>  flags set; they may have their ACC_VARARGS, ACC_BRIDGE and  
>  ACC_SYNTHETIC flags set and must not have any of the other flags in  
>  Table 4.5 set (JLS §9.4).

従ってJVMのレベルでインターフェースで`private`や`protected`なメソッドは扱えません。

一方[Java SE 8版のChapter 4. The class File
Format](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6)には次のように書かれています。

> Methods of interfaces may have any of the flags in Table 4.6-A set  
>  except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS  
>  §9.4). In a class file whose version number is less than 52.0, each  
>  method of an interface must have its ACC_PUBLIC and ACC_ABSTRACT flags  
>  set; in a class file whose version number is 52.0 or above, each  
>  method of an interface must have exactly one of its ACC_PUBLIC and  
>  ACC_PRIVATE flags set.

`protected`は相変わらずダメですが`private`は扱えるようになっています。

