Java: 1 つのファイルで複数のクラスを宣言する 質問する

Java: 1 つのファイルで複数のクラスを宣言する 質問する

Javaでは、1つのファイルで複数のトップレベルクラスを定義できますが、そのうちの1つだけがpublicである必要があります(JLS §7.6)。例として以下をご覧ください。

  1. この手法には、 ( inner、、に類似した)適切な名前がありますか?nestedanonymous

  2. 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しようとするとどうなるでしょうか? コンパイルは次のようなエラーで失敗します。BazBarFoo.java

Foo.java:2: cannot find symbol
symbol  : class Baz
location: class Foo
  private Baz baz;
          ^
1 error

よく考えてみると、これは理にかなっています。 がFooを参照しているのに、 (または)Bazがない場合、 javac はどのソース ファイルを調べるべきかをどうやって知るのでしょうか。Baz.javaBaz.class

代わりに、javac にFoo.javaと をBar.java同時にコンパイルするように指示するか、以前に をコンパイルしていた場合Bar.java( javacが見つけられるBaz.class場所に を残しておく)、またはが に加えてを参照する場合でも、このエラーは発生しなくなります。ただし、これにより、ビルド プロセスが非常に信頼性が低く、不安定になります。FooBarBaz

実際の制限は、「トップレベル クラスを別のファイルから参照しないでください。ただし、そのクラスが、そのファイルと同じ名前であるか、そのファイル内にある同じ名前の別のクラスを参照している場合を除きます」という感じで、理解するのが難しいため、通常は、各ファイルにトップレベル クラスを 1 つだけ配置するという、はるかに簡単な (ただし厳密な) 規則に従います。クラスをパブリックにするべきかどうかについて気が変わった場合にも、この規則の方が適しています。

新しいバージョンのjavacでは、このような状況で次のような警告も生成されることがあります-Xlint:all

auxiliary class Baz in ./Bar.java should not be accessed from outside its own source file

時々、誰もが特定の方法で物事を行うのには、本当に正当な理由があることがあります。

おすすめ記事