Javaでファイル名とは異なる名前のクラスをコンパイルできるのはなぜですか?


170

その中にファイルTest.javaと次のコードがあります。

public class Abcd
{
        //some code here

}

現在、クラスはコンパイルされませんが、public修飾子を削除すると、正常にコンパイルされます。

Javaの背後にある理由は何ですか。パブリックではないときに、ファイル名とは異なるクラス名をコンパイルすることができます。

私はそれが初心者の質問であることを知っていますが、良い説明を見つけることができません。


28
Javaだから。(公開されておらず、同じ命名規則に従う必要もないため。それを超えて、それを発明した人々に尋ねる必要があります。)
Dave Newton

2
「良い説明」があるとは思えません。これはパブリッククラスの要件でしたが、非パブリッククラスでは不要と見なされていました。
カヤマン2013年

2
同様の質問のようです: stackoverflow.com/questions/7633631/…–
sanket

4
なぜ、この質問のために非常に多くのupvotes、すべての最初の重複した質問:stackoverflow.com/questions/7633631/...
GMラメシュ

2
@ Ramesh:この質問のタイトルと内容が優れています(他の同様の質問よりも)
Jayan 2013年

回答:


325

根拠は、.javaファイルごとに複数のトップレベルクラスを許可することです。

イベントリスナーなどの多くのクラスはローカルでのみ使用され、Javaの最も古いバージョンではネストされたクラスをサポートしていませんでした。この「ファイル名=クラス名」ルールの緩和がなければ、そのようなクラスはそれぞれ独自のファイルを必要.javaとし、小さなファイルの無限の増殖と密結合コードの分散という避けられない結果が生じます。

Javaがネストされたクラスを導入するとすぐに、このルールの重要性は大幅に低下しました。今日では、何百ものJavaファイルを処理することができ、それを利用するJavaファイルに決して手を加えることはありません。


60
+1、これは実際に理由を提供しますが、これが問題です。
デイブニュートン

4
特に履歴情報の+1-ネスト/匿名クラスの出現により、同じ決定が今行われる場合(下位互換性を気にしない)、1つのトップレベルクラスだけを許可するほうがはるかに理にかなっていると思いますファイル。
Michael Berry、

1
@ berry120かなり可能性があります。これは、この許可により、コンパイル時のファイル検索が複雑になるためです。
Marko Topolnik 2013年

3
@Val他の人がテキストエディタとCLIツールを使用して開発することを希望するIDEが存在することを否定するのは、IDEを作成しなければ意味がないと言っているのと同じくらい愚かです。どちらのアプローチも、優れた開発者が高品質のコードを作成するために使用します。すべての開発者がそのうちの1つを解決してkumbayaを歌う確率よりも小さいのは、単一の最高のプログラミング言語が何であるかについて私たち全員が同意する確率です。
ダンはFirelightによっていじくります2013年

5
Emacs(またはVim、Pick your poison)とUnixシェルユーティリティの組み合わせは、最新のIDEほど簡単なものではなく、習得するのは難しいですが、2つの圧倒的な利点があります。私がこれまでに試したすべてのIDE:コードベースがどれほど巨大であってもクラッシュすることはなく、私のタイピングに追いつくことができます。
zwol 2013年

80

理由はドアプレートと同じです。誰かが公式にオフィスに居住している場合(公に宣言されています)、その人の名前がドアのタグに記載されている必要があります。「アレックス・ジョーンズ」や「探偵コロンボ」のように。誰かが部屋を訪問したり、職員に話しかけたり、床を掃除したりするだけの場合、その名前を正式にドアに貼る必要はありません。代わりに、ドアは「ユーティリティ」または「会議室」を読み取ることができます。

正式名またはMyClass.java 会議室またはTest.java


4
間違いなく興味深い類推。それがどのように直接関係しているかについての少しの説明があればさらに良いかもしれません。OPは接続を確立するのにいくつかの困難を伴う可能性があります(私は完全に理解していますが)
Andrew Barber '27

4
@AndrewBarber 1つのパブリッククラスをモデル化しておらず、ファイルを複数のパッケージプライベートクラスと共有しているため、類推は実際には当てはまりません。これは「ヘザーサンティー、マネージャー」と書かれた表札のようなものですが、部屋には実際にはヘザーと彼女の2人の秘書が含まれています。
Marko Topolnik 2013年

@MarkoTopolnik私はこれに関与すべきではありませんでした。私はクラスA です。類推では恐ろしいです。;)
アンドリューバーバー、

@AndrewBarberとにかく、書きたかった。あなたはただプッシュを与えただけです:)アナロジーも最も深刻な懸念を表すことができません:この機能のために、コンパイラーはすべてのファイルを解析してすべてのクラスを発見する必要があります。トップレベルのクラス。
Marko Topolnik 2013年

@AndrewBarber、アナロジーはディレクトリのアイデアに完全に適合します。長い廊下では、ドアのプレートをちらっと見るだけですぐに人を見つけることができます。各部屋に入って尋ねる必要はありません。
exebook 2013

29

Java仕様では、ファイルごとに最大1つのパブリッククラスしか持つことができないと規定されています。この場合、クラス名はファイル名と一致する必要があります。すべての非パブリッククラスには、ファイル名に関係なく、任意の名前を付けることができます。


20
しかし、これを「Javaの背後にある理由によって何が可能になるのか」ということですか。
Marko Topolnik 2013年

@MarkoTopolnikそれが私たちを妨げるものではないので:D
Maroun

8
@MarounMarounしかし、私たちを妨げない理由は何ですか?
Marko Topolnik 2013年

@Marko Javaでは、同じファイルで複数のクラスを定義できます(それらの1つだけがパブリックである限り)。同じパッケージ内のすべてのクラスには異なる名前を付ける必要があるため、非公開クラスにファイル名以外の名前を許可する以外に選択肢はありません。
isnot2bad 2013年

2
私の2セント:多分それはクラスパス内のクラスの迅速なローカリゼーションのためにこのように設計されました。この規則を使用すると、クラスの検出にはファイル名/パスの検査で十分です。この規則がなければ、クラスパスクラスローダは、クラスを見つけるために開いて、解析ファイルが必要になることがあります
アンドレイNicusan

13

それらを許可することは、ネストされたクラスの前提条件だと思います。特に匿名クラスは、必要な.javaファイルの数を劇的に減らします。これがサポートされていないと、それらが使用されているメインクラスとは別の独自のファイルに、単一のメソッドインターフェースを多数実装する必要があります(特にアクションリスナーについて考えています)。

OracleのWebサイトにあるNested Classes Javaチュートリアルには、すべてのネストされたクラスの適切な説明があり、それぞれの例が示されています。また、それらが役立つ理由もあります。

ネストされたクラスを使用する理由

ネストされたクラスを使用する説得力のある理由は次のとおりです。

  • これは、1つの場所でのみ使用されるクラスを論理的にグループ化する方法です。クラスが他の1つのクラスだけに役立つ場合は、そのクラスに埋め込んで2つをまとめることが論理的です。このような「ヘルパークラス」をネストすると、パッケージがより効率的になります。

  • カプセル化が向上します。2つのトップレベルのクラスAとBを考えます。Bは、そうでなければプライベートとして宣言されるAのメンバーにアクセスする必要があります。クラスA内でクラスBを非表示にすることで、Aのメンバーをプライベートに宣言し、Bがそれらにアクセスできるようになります。さらに、B自体を外部の世界から隠すことができます。

  • これにより、コードがより読みやすく、保守しやすくなります。最上位クラス内に小さなクラスをネストすると、コードが使用される場所の近くにコードが配置されます。

(強調鉱山)

初期の頃はJava仕様に慣れていませんが、クイック検索で内部クラスがJava 1.1に追加されたことがわかります。


タイプが別のタイプ内でのみ有用であるが、前者のタイプのインスタンスが後者のインスタンスに関連付けられていない場合、どうすればよいですか?
スーパーキャット2013年

ネストされたクラスは、ラムダを実行するJava 1.2の方法、または「すべてがオブジェクトである場合のファーストクラス関数」です。これは1.8構文で変更されています。これらは、Javaの型システムで代数データ型をモデル化するときにも使用されます。
hawkeye 2013年

12

私はそれを逆に見ます。プログラマーがクラス名とファイル名の両方を個別に選択するのは自然な状況です。おそらく、コンパイル時にパッケージの外部からパブリッククラスを簡単に見つけるために、パブリッククラスを対応する名前のファイルに含めるという特別な制限があります。


4

Javaでは大文字と小文字が区別されますが、ファイルシステムでは区別されないことに注意してください。ファイルのベース名が「abcd」で、クラスが「Abcd」の場合、大文字と小文字を区別しないファイルシステムのルールに準拠しますか?大文字と小文字を区別するものに移植した場合は確かにそうではありません。

または、ABCDという名前のクラスとAbcdというクラスがあったとします(悪い考えですが、入り込まないでください。それが起こる可能性があります)。プログラムは、大文字と小文字を区別しないファイルシステムに移植されています。これで、ファイルの名前を変更するだけでなく、クラス、おっと!

または、ファイルがない場合はどうなりますか?標準入力で入力を受け取ることができるJavaコンパイラーがあるとします。それでは、クラスは「StandardInput」という名前にする必要がありますか?

クラス名の後にファイル名を付けることを要求することの意味を合理的に調査すると、複数の点でそれが悪い考えであることがわかります。


私はあなたが言わなければならないことに同意しますが、おそらく非公開クラス名を異なるものにすることを許可することによってネーミングアーキテクチャに起因するいくつかの問題が緩和できる範囲を除いて、それが質問に特に答えることを知りませんファイル名。ところで、大文字と小文字の区別に関しては、私は任意の範囲で、言語を導出している場合は、されたFoo、識別子を宣言したFOOfoofOoなど、すべての彼らは、外側のスコープ内に存在していても「未定義」されるだろう。このような設計により、ファイル名の大文字と小文字が区別される問題が解消されます。
スーパーキャット2013年

3

また、多くの回答が指摘し損なったもう1つの点は、public宣言がないと、JVMはどのクラスのメインメソッドを呼び出す必要があるかを決して認識しないということです。1つの.javaファイルで宣言されたすべてのクラスはすべてメインメソッドを持つことができますが、メインメソッドはパブリックとしてマークされたクラスでのみ実行されます。HTH


0

Javaファイルには複数のクラスを含めることができるため、1つのJavaファイルに2つのクラスが含まれる場合があります。ただし、Javaファイルには、パブリッククラスが含まれている場合、ファイル名と同じ名前のクラスが含まれている必要があります。


いいえ、そのルールはパブリッククラスにのみ適用されます。
デッドボーイ2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.