Javaでは、1つのファイルで複数のトップレベルクラスを定義できますが、そのうちの1つだけがpublicである必要があります(JLS §7.6)。例として以下をご覧ください。
この手法には、 (
inner
、、に類似した)適切な名前がありますか?nested
anonymous
JLS では、システムがこれらのセカンダリ クラスを「パッケージの他のコンパイル単位のコードから参照できない」という制限を強制する可能性があるとされています。たとえば、セカンダリ クラスをパッケージ プライベートとして扱うことはできません。これは本当に Java 実装間で変わるものなのでしょうか?
例: PublicClass.java:
package com.example.multiple;
public class PublicClass {
PrivateImpl impl = new PrivateImpl();
}
class PrivateImpl {
int implementationData;
}
ベストアンサー1
Javac はこれを積極的に禁止しているわけではありませんが、別のファイルからトップレベル クラスを参照する場合は、そのクラスが含まれるファイルと同じ名前でない限り、そのクラスを参照しない方がよいという制限があります。
2 つのファイルがあるとしFoo.java
ますBar.java
。
Foo.java
含まれるもの:
public class Foo
Bar.java
含まれるもの:
public class Bar
class Baz
また、すべてのクラスが同じパッケージ内にある(そしてファイルが同じディレクトリ内にある)とします。
を参照しているが参照しておらず、 をコンパイルFoo
しようとするとどうなるでしょうか? コンパイルは次のようなエラーで失敗します。Baz
Bar
Foo.java
Foo.java:2: cannot find symbol
symbol : class Baz
location: class Foo
private Baz baz;
^
1 error
よく考えてみると、これは理にかなっています。 がFoo
を参照しているのに、 (または)Baz
がない場合、 javac はどのソース ファイルを調べるべきかをどうやって知るのでしょうか。Baz.java
Baz.class
代わりに、javac にFoo.java
と をBar.java
同時にコンパイルするように指示するか、以前に をコンパイルしていた場合Bar.java
( javacが見つけられるBaz.class
場所に を残しておく)、またはが に加えてを参照する場合でも、このエラーは発生しなくなります。ただし、これにより、ビルド プロセスが非常に信頼性が低く、不安定になります。Foo
Bar
Baz
実際の制限は、「トップレベル クラスを別のファイルから参照しないでください。ただし、そのクラスが、そのファイルと同じ名前であるか、そのファイル内にある同じ名前の別のクラスを参照している場合を除きます」という感じで、理解するのが難しいため、通常は、各ファイルにトップレベル クラスを 1 つだけ配置するという、はるかに簡単な (ただし厳密な) 規則に従います。クラスをパブリックにするべきかどうかについて気が変わった場合にも、この規則の方が適しています。
新しいバージョンのjavacでは、このような状況で次のような警告も生成されることがあります-Xlint:all
。
auxiliary class Baz in ./Bar.java should not be accessed from outside its own source file
時々、誰もが特定の方法で物事を行うのには、本当に正当な理由があることがあります。