2012-07-24 14 views
10

コードクラス宣言のメンバインターフェイスは暗黙的にpublicになっていますか?

私はメンバーインターフェイスで次のクラスがあります。

package com.example.withinterface; 

public class SomeClass { 

    interface SomeInterface { 

     void doSomething(); 
    } 
} 

とそれにアクセスしようとしている別のクラス:主に

package com.example.withinterface.main; 

import com.example.withinterface.SomeClass; 

public class Main { 

    public static void main(String[] argss) { 
     System.out.println(SomeClass.SomeInterface.class); 
    } 
} 

エラー

をjavacから次のエラーが表示されます。SomeInterface is not public in SomeClass; cannot be accessed from outside package

Eclipseでは:SomeInterface is not public in SomeClass; cannot be accessed from outside packageです。

どちらもJava 7としてコンパイルしています。SomeInterfaceを作成するとすべてがコンパイルされますpublic

しかし仕様が

Java Language Specification for Java 7言い、これは言う:

メンバーインターフェイスは、その宣言直接 が別のクラスまたはインタフェース宣言で囲まれているインターフェースです。

アクセス修飾子が指定されていない限り、クラス宣言のメンバーインターフェイスは暗黙的にパブリック(§6.6) です。

Java Language Specification for Java 5は、2番目の文を持っていないようです。

質問

のでSomeInterface公共考えるべきではないと主がコンパイルされないでしょうか?

更新Ajay Georgeによって示唆されるように

が、これは確かにan error in the Java Language Specification 7(感謝JamesB)でした。その間、仕様は修正され、間違った文が削除されました。 Last version in Archive.org with the incorrect sentence

+0

hh。特に断らない限り、私はいつも全てがパッケージ保護されているとみなしていた私は新しいことを学んだと思う。 –

+1

これは、アクセス修飾子を持たないメンバーがパッケージにアクセスできるためだと思います。だから他のパッケージでは使用できません –

+0

@Desolatorあなたはその質問を読んだことがありますか?メンバインタフェースは**デフォルトでpublicです**。 –

答えて

2

仕様が間違っていると思います。 ここにjavapのコードを出力します。

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

インターフェイスをpublicに変更してから再コンパイルしました。

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
public interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

Innerクラスの違いに注意してください。

+2

私は同意します。 JLSは明らかに間違っています。 Java 7 JDKを使用すると、コードはメンバインタフェースが**明示的にpublic宣言されている場合にのみコンパイルされます。 – JamesB

+0

@JamesBいいえ、仕様**は定義上間違っていることはできません。間違っているのは実装です。 JLSは記述的ではありませんが、**規範的**です。 –

+0

@MarkoTopolnikそれはタイプミスのように見えます:* "クラス**宣言のメンバインタフェースは暗黙のうちに公開されています" *おそらく* "インタフェース**宣言のメンバインタフェースは暗黙のうちに公開されます" *でしょう。前の文の文脈では意味をなさないでしょう:* "別のクラスまたはインタフェースの宣言に囲まれています" *。 – assylias

関連する問題