Javaの文法
Javaの文法の記事では、プログラミング言語Javaの構文（シンタックス、）について解説する。また（翻訳元の時点で）過剰な加筆がされており、それ以外についても解説している。
Javaのデータ型には大別して、プリミティブ型と参照型がある。
もしくはとも。
プリミティブ型はオブジェクトではなく、スーパークラスを持たない。すべての参照型はオブジェクト型を表すクラスから派生する。オブジェクトは参照型のインスタンスである。クラスcodice_1は既定でから派生する参照型である。列挙型codice_2は抽象クラスから暗黙的に派生する参照型である。
リフレクション機能のための「クラスを表現するクラス（メタクラス）」としてが存在するが、クラス自体はオブジェクトではない。
リテラルの例を示す。
Javaは1バイト整数の型（byte）と文字の型（char）とを区別する。なお、charは、名前に反して必ずしも文字を表現していない場合があり得る。すなわち、実際にはUCS-2（UTF-16）による、いわゆるダブルバイトである。J2SE 5.0以降ではサロゲートAPIによって、サロゲートペアに対応した。
JavaプログラムのソースコードおよびソースファイルはUTF-8でエンコードするのが基本である。Unocodeに対応したエンコードであれば、Javaプログラムのソースコードに直接Unicode文字を記述することもできる。なお、codice_6コンパイルオプションを指定することで、対応する任意のエンコードを使用することもできる。ロケール依存のコードページ（日本語版Microsoft Windowsで使われているCP932等）を利用することもできる。
文字列リテラルやコメントの他、クラス名や変数名も国際化に対応している。例えば、次のソースコードはJavaのコードとして正しく解釈されコンパイルされ実行できる。ここではクラス名、変数名、および文字列リテラルとして日本語の文字を使っている。
関係演算子(==と!=)を参照型に対して用いた場合、そこで比較されるのは参照先のオブジェクトが同じかどうかであり、オブジェクトの中身の値が一致するか否かではない。オブジェクトの中身を比較したい場合はメソッドを使用する。instanceof演算子は、オブジェクトが指定クラスのインスタンスであるか否かを判定するために用いる。
三項演算子は二つの記号codice_7とcodice_8を組み合わせて記述する。条件演算子とも呼ぶ。構文は以下である。
条件がcodice_9であるとき、式1の値をとる。そうでない場合は式2の値をとる。
例:
(訳注:
上の通り、&&と||は左のオペランドしか評価しない可能性がある。これに対し、ビット演算子にも挙げられている&と|を代わりに書いた場合は、左右のオペランド両方が完全に評価される。実用上は&&と||を用いるのが一般的である)
if ("expr") { switch ("expr") { for ("initial-expr"; "cond-expr"; "incr-expr") {
J2SE 5.0では、for-each文と呼ばれる新機能が追加された。これは集合の中の全要素を順番に参照するような処理を大いに簡素化する。このような場合、従来は次の例に示すような反復子 (iterator) を書かねばならなかった:
for-each文はこのメソッドを大いに簡素化する:
この例の動作としては、codice_14に含まれる全てのについて、長さを取得してcodice_15に加算する。
while ("expr") {
do {例:
Javaのキーワードには「goto」という綴りも含まれているが、goto文は無い（他にもうひとつ、constも同様に、キーワードとして予約されているが、予約されているだけで使われていない）。
Javaでは別のクラスやインタフェース内部で宣言された「ネスト」されたクラスを作ることができる。ネストされていないクラスは「トップレベル」クラスと呼ばれる。非staticなネストされたクラスのことは「内部クラス」と呼ぶ。
クラスを宣言する際は以下の修飾子を付けることができる:
Javaのクラス定義ブロックはセミコロンcodice_20で終わらせる必要はない点に注意。この点はC++の文法と異なる。
インタフェースとは、実装の詳細がいっさいない抽象クラスである。その目的は複数のクラスの用途をまとめて定義することにある。共通のインタフェースを実装する複数のクラスは、そのインタフェース型のコンテキストにしたがって互いに交換可能とすることができる。インタフェースはまた、抽象化 – クラスの実装方法を隠蔽すること – という考え方を強制するのにも役立つ。
インタフェースは抽象メソッドとstatic finalフィールドだけを含むことができる。インタフェースメソッドはデフォルトでpublicかつabstractであり（実装を持たない）、インタフェースフィールドはデフォルトで public static final である。
Javaは完全なの多重継承はサポートしていない。C++における多重継承には、複数の親クラスや型から複数回継承したフィールドやメソッドを識別するための複雑なルールが伴う。インタフェースを実装から分離することにより、インタフェースはより単純かつ明快に多重継承が持つ利点の多くを提供する。もっとも、多重継承を避ける代価としてコードは若干冗長になる。というのは、インタフェースはクラスのシグネチャを定義するのみで実装を持てないため、インタフェースを継承する全てのクラスは定義されたメソッドをいちいち実装しなければならないからである。純粋な多重継承であれば実装自体も継承されるのでこのようなことはない。
なお、Java 8ではインタフェースのデフォルトメソッドにより実装の多重継承をサポートするようになった。
Javaのインタフェースは Objective-C規約のコンセプトによく似た振る舞いをする。
クラスは、一つのクラスを継承できるのに加えて、implementsキーワードを用いて一つ以上のインタフェースを実装することができる。
以下の例では、codice_24インタフェースを実装する非codice_16クラスは、引数無しで戻り型がcodice_26であるcodice_27という名前の非抽象メソッドを定義しなければならない。そのメソッドの実装と機能は各々のクラスによって決定される。
このコンセプトにはさまざまな使い道がある。例えば:
上の配列に含まれる全てのオブジェクトはcodice_28メソッドを持つことが保証されるので、codice_29メソッドはcodice_30オブジェクトと他の如何なるcodice_24オブジェクトをも区別する必要がない。
インタフェースはcodice_32キーワードを用いて一つ以上のインタフェースを継承することができる。
結果として生じるインタフェースを実装するクラスは、元のインタフェースに含まれたメソッドをも併せて定義しなければならない。
アクセス修飾子は、そのクラスやクラスメンバにアクセス可能なコードが誰であるかを決定する。
デフォルトでは、Javaのクラスは、それら自身のJavaパッケージからのみアクセスできる。これは、クラスのパッケージが、裏に隠れて機能を実行するようなＡＰＩを提供することを可能とする。外にアクセスを公開されたクラスの動作を、隠されたクラスが支える形になる。"クラスメンバ"とはフィールド、メソッド、コンストラクタ、クラス内で定義されたネストされたクラスのことである。アクセス制限が厳しいものから並べると、クラスメンバのアクセス修飾子は次の通り。
メソッドをオーバライドする際、そのメソッドのアクセス権を「より厳しく」することはできない。さもなくば親クラスのインタフェース契約を壊してしまうからである。したがってオーバライドされる場合、publicメソッドはpublicとして宣言されねばならず、protectedメソッドをデフォルトアクセス権（修飾子省略）とすることはできない。しかしながら、メソッドをオーバライドしてアクセス権を「より緩める」ことは許される。したがってオーバライドする際、デフォルト (パッケージ) アクセス権のメソッドはprotectedまたはpublicとして宣言することができ、protectedメソッドはpublicとして宣言することができる。
アクセス修飾子に加えて、データフィールドは以下の修飾子によって宣言される:
staticとfinal両方を宣言されたフィールドは事実上、定数である。codice_34はそのフィールドがそのクラスにおいてただ一つのみ存在することを示し、codice_37はそのフィールドがただ一度のみ値を設定（初期化）可能であることを意味する。
「イニシャライザ」（初期化子）はフィールドのイニシャライザと同時に実行されるコードのブロックである。
「スタティックイニシャライザ」（静的初期化子）はstaticフィールドのイニシャライザと同時に実行されるコードのブロックである。静的フィールド初期化子と静的初期化子は宣言された順番に実行される。静的初期化はクラスがロードされた後で実行される。
「インスタンスイニシャライザ」（インスタンス初期化子）はインスタンスの (非codice_34な) フィールドの初期化子と同時に実行されるコードのブロックである。インスタンスフィールド初期化子とインスタンス初期化子は宣言された順番に実行される。
インスタンス初期化子とインスタンスフィールド初期化子はコンストラクタが呼び出された際に実行される。正確な実行順序としては、親クラスのコンストラクタが実行された後、かつ、自身のコンストラクタが実行される前、となる。
アクセス修飾子に加えて、メソッドには以下の修飾子を付けて宣言できる：
privateメソッドは自ずからfinalであり、abstractにはできない点に注意。
Java SE 5.0において、引数の個数が可変であるようなメソッドについての文法上の便宜()が追加された。これによって引数の個数が可変であるメソッドをタイプセーフに使用することが容易になる。最後のパラメタの後に「...」と書くと、Javaは全ての引数を配列に格納する：
このメソッドを呼ぶ際、プログラマは個々のpointsを単にカンマで区切って書けばよく、Pointオブジェクトの配列をわざわざ用意する必要はない。このメソッドの内部でpointsを参照する際はpoints[0]、points[1]、などのように書ける。pointsが渡されていない場合、配列のlengthは0となる。可変個の引数と別に固定的に必要なパラメタがある場合は、それらのパラメタは可変引数に先立って指定すればよい。
コンストラクタはオブジェクトが割り当てられた後すぐに呼び出され、オブジェクトの初期処理を行う。コンストラクタは典型的にはnewキーワードを使用して呼び出されるが、リフレクションを使用して呼ぶこともできる。リフレクション機能はjava.lang.reflectパッケージより提供される。
コンストラクタを宣言する際に使える修飾子はアクセス修飾子のみである。クラスのメソッドは継承されるので、全てのクラスにて使用できる。
メソッドは現在のオブジェクトのコピーである新しいオブジェクトを返す。クラスは、それがクローンできることを明示するためにマーカーインタフェースを実装しなければならない。
メソッドはそのオブジェクトともう一つのオブジェクトを比較し、二つのオブジェクトが同一かどうかをcodice_50型の値で返す。意味的には、このメソッドはオブジェクトの内容を比較するのに対し、関係演算子"codice_51"はオブジェクトの参照を比較する。codice_49メソッドはパッケージにあるデータ構造クラスの多くで使われる。これらのデータ構造クラスのいくつかはcodice_53メソッドにも依存している - codice_49とcodice_55との間の契約の詳細について、hashCodeメソッドを参照のこと。
メソッドはガベージコレクタがオブジェクトのメモリを解放する前に必ず一度だけ呼び出される。オブジェクトが消滅する前に実行しなければならない何らかの後処理がある場合、各クラスはcodice_56をオーバーライドすることができる。とはいえほとんどのオブジェクトはcodice_56をわざわざオーバーライドする必要はない。
codice_56メソッドがいつ呼ばれるかは保証されない。複数のオブジェクトのcodice_56がどのような順番で呼ばれるかも不定である。もしJVMがガベージコレクションを実行せずに終了するならば、OSがオブジェクトを解放する可能性があり、その場合codice_56メソッドは呼ばれない。
codice_56メソッドは、他のクラスから呼ばれるのを防ぐために、常にprotectedとして宣言されるべきである。
メソッドはオブジェクトをインスタンス化するために使われたクラスのオブジェクトを返す。このクラスオブジェクトはJavaにおけるリフレクションの基本となる。その他のリフレクション機能はcodice_64パッケージにて提供される。
メソッドは連想配列にオブジェクトを保存するための「ハッシュ値」として(codice_12型の)整数を返す。インタフェースを実装するクラスは連想配列を提供しcodice_55メソッドに依存する。codice_55の良い実装は安定 (不変) かつ均等に分布するハッシュ値を返す (異なるオブジェクトのハッシュ値は互いに異なる値となる傾向を持ち、かつハッシュ値は整数値の範囲内で均等に分布する)。
連想配列はcodice_49とcodice_55の両メソッドに依存するため、これら二つのメソッドの間では、オブジェクトがcodice_71に挿入される場合に関する或る重要な契約が維持されねばならない：この契約を維持するために、codice_49メソッドをオーバーライドしたクラスは同時にcodice_55メソッドもオーバーライドし、逆もまた同様として、codice_55とcodice_49が常に同じ性質（または同じ性質の一部）に基づくようにしなければならない。
マップがオブジェクトとの間に有する更なる契約は、ひとたびオブジェクトがマップに挿入されたなら、codice_55 と codice_49両メソッドの結果は以後変わらないということである。したがって、一般にハッシュ関数はオブジェクトの不変(変更不能)な属性に基くように設計するのが良い。
メソッドはオブジェクトの文字列表現をで返すものである。codice_81メソッドは、オブジェクトが文字列連結演算子(codice_3とcodice_4)のオペランドとして使われたとき、コンパイラによって暗黙のうちに呼び出される。
全てのオブジェクトは、そのオブジェクトに関連するスレッドについての二つの待ちリストを持つ。一つの待ちリストはsynchronizedキーワードに伴いオブジェクトをミューテックス排他するために使われる。もしミューテックスが他スレッドによって排他されているならば、自スレッドは排他を待っているスレッドのリストに追加される。もう一つの待ちリストはスレッド間でシグナルを送るためのもので、これはwait、notify、notifyAllの各メソッドを通して使用される。
wait/notifyを用いるとスレッド間での能率的な連携が可能となる。あるスレッドが別スレッドでの処理が終わるのを待ち合わせる必要があるとき、または何らかのイベントが発生するまで待たねばならないとき、スレッドはその実行を一時停止してイベントが発生した際に通知を受け取ることができる。これはポーリングとは対照的である。ポーリングにおいては、スレッドは一定時間スリープしてはフラグや他の状態表示をチェックする処理を繰り返す。ポーリングはスレッドがチェックを繰り返さねばならないという点でより計算コストが掛かる上に、実際にチェックしてみるまでイベント発生を検知できないという意味で鈍感でもある。
codice_85メソッドには三つのオーバーロード版があり、タイムアウト値の指定方法がそれぞれ異なる：、、の三つである。一つ目のメソッドはタイムアウト値が0であり、これはタイムアウトが発生しないことを意味する。二つ目のメソッドはミリ秒単位のタイムアウト値を取る。三つ目のメソッドはナノ秒単位のタイムアウト値を取り、これはcodice_87として計算される。
codice_85を呼んだスレッドは待機状態となり、そのオブジェクトの待ちリストに追加される。そのスレッドは以下の三つのイベントのいずれか一つが起きるまで、オブジェクトの待ちリスト上に留まる：codice_85メソッドは、そのオブジェクトについての同期(synchronized)ブロックまたは同期(synchronized)メソッドの内部からのみ呼ばねばならない。これはcodice_85とcodice_89との間で競合を起こさないためである。スレッドが待ちリストに入るとき、そのスレッドはそのオブジェクトのミューテックス排他を解除する。そのスレッドが待ちリストから削除され実行可能スレッドとなった際に、そのスレッドは走行を再開するのに先立ってそのオブジェクトのミューテックスを改めて排他しなければならない。
と メソッドはオブジェクトの待ちリストから一つ以上のスレッドを削除し、それらを実行可能スレッドとする。codice_89は待ちリストから1スレッドのみ削除し、codice_90は待ちリストから全てのスレッドを削除する。codice_89がどのスレッドをリストから削除するかは規定されておらず、JVMの実装に依存する。
codice_89とcodice_90メソッドは、そのオブジェクトについての同期(synchronized)ブロックまたは同期(synchronized)メソッドの内部からのみ呼ばねばならない。これはcodice_85とcodice_89との間で競合を起こさないためである。
J2SE1.4よりも前のバージョンのJavaはストリーム・ベースののみをサポートしていた。これは1ストリームにつき1スレッドを必要とした。何故ならストリームの入力または出力を行おうとすると、それが完了するまでそのスレッドは完全に待ちに入ってしまい、他の処理がいっさい行えなくなったからである。これは、Javaを用いたネットワークサービスを構築する上で、スケーラビリティと性能双方の面で大きな問題となっていた。J2SE1.4以降ではフレームワークとしてNIO (New I/O) が導入され、このスケーラビリティ問題は修正された (ただし、サンによるNIO APIの実装にはまだ多くの問題点がある)。
非ブロッキングIOフレームワークは、以前のブロッキングIOフレームワークより遥かに複雑ではあるが、一つのスレッドで任意の数の"チャネル"を扱うことができる。このフレームワークはをベースとしている。
Javaはケースセンシティブ (大文字小文字を区別する) である。
コメントの文法はC++と同じである。
なお、ドキュメンテーションコメントとしてJavadoc方式をサポートする。