その中にファイルTest.java
と次のコードがあります。
public class Abcd
{
//some code here
}
現在、クラスはコンパイルされませんが、public
修飾子を削除すると、正常にコンパイルされます。
Javaの背後にある理由は何ですか。パブリックではないときに、ファイル名とは異なるクラス名をコンパイルすることができます。
私はそれが初心者の質問であることを知っていますが、良い説明を見つけることができません。
その中にファイルTest.java
と次のコードがあります。
public class Abcd
{
//some code here
}
現在、クラスはコンパイルされませんが、public
修飾子を削除すると、正常にコンパイルされます。
Javaの背後にある理由は何ですか。パブリックではないときに、ファイル名とは異なるクラス名をコンパイルすることができます。
私はそれが初心者の質問であることを知っていますが、良い説明を見つけることができません。
回答:
根拠は、.java
ファイルごとに複数のトップレベルクラスを許可することです。
イベントリスナーなどの多くのクラスはローカルでのみ使用され、Javaの最も古いバージョンではネストされたクラスをサポートしていませんでした。この「ファイル名=クラス名」ルールの緩和がなければ、そのようなクラスはそれぞれ独自のファイルを必要.java
とし、小さなファイルの無限の増殖と密結合コードの分散という避けられない結果が生じます。
Javaがネストされたクラスを導入するとすぐに、このルールの重要性は大幅に低下しました。今日では、何百ものJavaファイルを処理することができ、それを利用するJavaファイルに決して手を加えることはありません。
理由はドアプレートと同じです。誰かが公式にオフィスに居住している場合(公に宣言されています)、その人の名前がドアのタグに記載されている必要があります。「アレックス・ジョーンズ」や「探偵コロンボ」のように。誰かが部屋を訪問したり、職員に話しかけたり、床を掃除したりするだけの場合、その名前を正式にドアに貼る必要はありません。代わりに、ドアは「ユーティリティ」または「会議室」を読み取ることができます。
Java仕様では、ファイルごとに最大1つのパブリッククラスしか持つことができないと規定されています。この場合、クラス名はファイル名と一致する必要があります。すべての非パブリッククラスには、ファイル名に関係なく、任意の名前を付けることができます。
それらを許可することは、ネストされたクラスの前提条件だと思います。特に匿名クラスは、必要な.javaファイルの数を劇的に減らします。これがサポートされていないと、それらが使用されているメインクラスとは別の独自のファイルに、単一のメソッドインターフェースを多数実装する必要があります(特にアクションリスナーについて考えています)。
OracleのWebサイトにあるNested Classes Javaチュートリアルには、すべてのネストされたクラスの適切な説明があり、それぞれの例が示されています。また、それらが役立つ理由もあります。
ネストされたクラスを使用する理由
ネストされたクラスを使用する説得力のある理由は次のとおりです。
これは、1つの場所でのみ使用されるクラスを論理的にグループ化する方法です。クラスが他の1つのクラスだけに役立つ場合は、そのクラスに埋め込んで2つをまとめることが論理的です。このような「ヘルパークラス」をネストすると、パッケージがより効率的になります。
カプセル化が向上します。2つのトップレベルのクラスAとBを考えます。Bは、そうでなければプライベートとして宣言されるAのメンバーにアクセスする必要があります。クラスA内でクラスBを非表示にすることで、Aのメンバーをプライベートに宣言し、Bがそれらにアクセスできるようになります。さらに、B自体を外部の世界から隠すことができます。
これにより、コードがより読みやすく、保守しやすくなります。最上位クラス内に小さなクラスをネストすると、コードが使用される場所の近くにコードが配置されます。
(強調鉱山)
初期の頃はJava仕様に慣れていませんが、クイック検索で内部クラスがJava 1.1に追加されたことがわかります。
私はそれを逆に見ます。プログラマーがクラス名とファイル名の両方を個別に選択するのは自然な状況です。おそらく、コンパイル時にパッケージの外部からパブリッククラスを簡単に見つけるために、パブリッククラスを対応する名前のファイルに含めるという特別な制限があります。
Javaでは大文字と小文字が区別されますが、ファイルシステムでは区別されないことに注意してください。ファイルのベース名が「abcd」で、クラスが「Abcd」の場合、大文字と小文字を区別しないファイルシステムのルールに準拠しますか?大文字と小文字を区別するものに移植した場合は確かにそうではありません。
または、ABCDという名前のクラスとAbcdというクラスがあったとします(悪い考えですが、入り込まないでください。それが起こる可能性があります)。プログラムは、大文字と小文字を区別しないファイルシステムに移植されています。これで、ファイルの名前を変更するだけでなく、クラス、おっと!
または、ファイルがない場合はどうなりますか?標準入力で入力を受け取ることができるJavaコンパイラーがあるとします。それでは、クラスは「StandardInput」という名前にする必要がありますか?
クラス名の後にファイル名を付けることを要求することの意味を合理的に調査すると、複数の点でそれが悪い考えであることがわかります。
Foo
、識別子を宣言したFOO
、foo
、fOo
など、すべての彼らは、外側のスコープ内に存在していても「未定義」されるだろう。このような設計により、ファイル名の大文字と小文字が区別される問題が解消されます。
Javaファイルには複数のクラスを含めることができるため、1つのJavaファイルに2つのクラスが含まれる場合があります。ただし、Javaファイルには、パブリッククラスが含まれている場合、ファイル名と同じ名前のクラスが含まれている必要があります。