キーワード (Java)
この項目ではJavaにおけるキーワード(予約語の記事を参照)に関して説明する。全部で50個ある。
この項目は、プログラムの細かい説明には立ち入らず、他の言語と比較できるような説明を目的としている。
プリミティブ型名や分岐処理 (if, switch)、反復処理 (for, while) などの基本的な構文とキーワードはC言語およびC++と共通するものが多い。クラスや例外処理に関してはC++類似の構文とキーワードが多い。
プリミティブ型の名前である。C言語およびC++と共通するものが多い。ただし内部表現は処理系依存ではなく、言語仕様によって厳密に定められている。
byte, short, int, long
8ビット、16ビット、32ビット、64ビットの整数型。2の補数で表現される。Javaには符号なしの整数型がなく、C/C++で使われる unsigned はない。
float, double
32ビット単精度と64ビット倍精度の浮動小数点数型。IEEE 754準拠。
boolean
論理型。booleanはC言語(C99)における_Bool、C++におけるboolに相当する。
char
文字型。intおよびlongには暗黙的に代入可能。C/C++のcharとは異なり、16ビットのUnicode文字(UTF-16)を保持する。
void
これはプリミティブ型ではないが、型と同じ文脈で使うキーワードなのでここに分類する。メソッドに戻り値がないことを宣言する。void (コンピュータ)も参照のこと。
以下はキーワードと同様に扱われるが、定義では論理値リテラル、またはnullリテラルというリテラルである。
true, false
論理値を表すリテラル。
null
null型という特殊な型のリテラル。Nullも参照。
C言語およびC++と共通のキーワードを使用している。
if, else
switch, case, default
for, while, do
continue - ループの現在の反復 (iteration) をスキップする
break - ループのブロックから抜け出す
return - メソッドから抜け出す。戻り値のあるものは値やオブジェクトの参照を返す。
package
自クラスのパッケージを宣言する。Javaではパッケージと呼ばれるツリー構造でクラス群を分類している。クラスやメンバにアクセス修飾子 (後述する public, protected, private) を付けることにより、パッケージ内外でクラスやクラスのメンバにアクセス可能な範囲が変わってくる。
import
自クラスの所属するパッケージとは異なるパッケージにあるクラスを使用するときにこの宣言でインポートする。
class
クラスの定義。例えば、以下のように宣言する。それぞれについてはこの後、説明する。
例1 public class クラス名 { ... }
例2 public class クラス名 extends 親クラス名 { ... }
例3 public class クラス名 implements インタフェース名1, インタフェース名2, ... { ... }
例4 public class クラス名 extends 親クラス名 implements インタフェース名1, ... { ... }
interface
インタフェースの定義。Javaのインタフェースとは、定義のみで実装をもたない抽象型であり、型の多重継承に使用される。インタフェースのインスタンスを直接生成することはできない。サブクラスでインタフェースを実装して使用する。実装するインタフェースはカンマ区切りで複数並べることができる。
例1 public interface インタフェース名 { ... }
例2 public interface インタフェース名 extends 上位インタフェース名1, 上位インタフェース名2, ... { ... }
extends
class の宣言で他のクラスを継承するときに使用する。Javaのクラスは1つのスーパークラスのみ継承可能で、多重継承(実装の多重継承)はできない (参考: 菱形継承問題)。interfaceの宣言では一つ以上のインタフェースを継承するときに使用する。インタフェースがインタフェースを継承するだけなので、こちらの場合は多重継承が可能。
implements
class の宣言で、インタフェースを実装するときに使用する。カンマ区切りで並べた複数のインタフェースを実装することができる。
this
自クラスを明示するときに使用する。コンストラクタ内から他の引数のコンストラクタを呼ぶときに使用するのが一般的である。また、例えば、コンストラクタの場合はthis(引数)、メソッドの場合はthis.メソッド名(引数) などのように使い、親クラスに同一名・同一引数のメソッドがあるときに明示的に区別できるようにする。こちらは、ローカル変数や同じクラス内メソッドや上位クラスに同名のメソッドが存在しない場合はthisを省略できる。内部クラスのコード領域で外部クラスのインスタンスへの参照を得るときの構文(OuterClass.this)でも使用される。
super
上位クラスのコンストラクタ、フィールド、メソッドにアクセスするときに使用する。上位クラスのコンストラクタを呼び出すときは単にsuper(引数)と書き、メソッドを呼び出すときはsuper.メソッド名(引数) などのように使う。フィールドやメソッドの場合は、自クラスに同一のものがない場合は super の記述を省略できる。
new
コンストラクタの呼び出し。インスタンスを生成するときに使用する。
例:
instanceof
指定されたクラスのオブジェクトかどうか、あるいは指定されたインタフェースを実装しているオブジェクトかどうかを判定する。a instanceof ClassName とした場合、a が ClassName のオブジェクトか、その派生クラスのオブジェクトであれば true になる。ClassName の箇所にオブジェクトの変数名を記述することはできない。
クラス、メンバの宣言に付けられる修飾子である。
public, protected, private
クラス、メンバのアクセス制御を指示する修飾子(アクセス修飾子)である。外部からアクセス可能な範囲を決める。Javaでは4つの段階が設けられ、以下の番号が大きくなるほど外部からのアクセスが制約される。
publicでは、すべてのクラスからアクセスできる。
protectedでは、同一パッケージにあるクラスかサブクラスからのみアクセスできる。異なるパッケージでサブクラスでないクラスからはアクセスできない。クラスを修飾することはできない (内部クラスは例外)。
アクセス修飾子がない場合は、同一のパッケージ内のクラスからのみアクセスできる。サブクラスであってもパッケージが異なる場合はアクセスできない。
privateでは、他のクラスからはアクセスできず、自クラスからのみアクセスできる。クラスに修飾することはできない (内部クラスは例外)。
Java SE 1.0ではprivate protectedという組み合わせを使用して、自分自身とサブクラスからのアクセスができるが同じパッケージ内の他のクラスからはアクセスできないというアクセス権を使用することができたが、これはJava SE 1.1以降から廃止され利用することができなくなった。
final
フィールドに付けられた場合は再代入を禁止する。メソッド宣言に付けられた場合は、下位クラスで上書きできないことを表す。クラス宣言に付けられた場合は、継承できないことを表す。なお、Javaでは、final宣言されたフィールドで、宣言部では初期化せずコンストラクタ内で1回だけ代入できる記述も行える。abstractとの併用はできない。メソッドの引数やローカル変数に使用すればその引数やローカル変数に対して再代入を許さないため、堅牢性の高いメソッドを作ることができる。final修飾子は「イミュータブル (不変)」なクラスを実装するときに役立つ。
例1:
例2:
static
フィールドに付けられた場合は、クラスに属する変数(クラス変数、静的フィールド、クラスフィールド)が確保されることを表す。この修飾子のついたフィールドは、インスタンスがいくつ生成されてもフィールドの実体は1つで、すべてのインスタンスの間で共有される。
記述例:
メソッドに付けられた場合は、オブジェクトを生成しなくても直接呼び出せるメソッド(静的メソッド、クラスメソッド)であることを表す。手続き型言語の関数と同じ扱いになる。
例:
クラス内にstatic {...}というブロックが現れた場合は、そのクラスが最初に参照されたときにそのブロック内のコードを実行する。これを静的初期化子と呼び、主にstatic finalな配列やjava/utilオブジェクトの初期化などに利用される。データベースにアクセスするためにJDBCドライバを呼び出すClass.forName("ドライバ名")もこの静的初期化子を呼び出している。
例:
入れ子にされたクラス(ネストされたクラス: nested class)のうち、static修飾されていないものは内部クラス (inner class) と呼ばれ、暗黙的に外側のクラスのインスタンスをキャプチャして参照することができるが、このネストクラスをstatic修飾すると静的ネストクラス (static nested class) となり、暗黙的に外側のクラスのインスタンスを参照できなくなる。
例:
abstract
クラスまたはメソッドに付けられる修飾子である。finalと併用することはできない。Javaでは、実装されないメソッドがあるクラスを作成することができる。抽象クラス自身のインスタンスを作成することはできない。似たものとしてインタフェースがあるが、abstract class は以下の点においてインタフェースと異なる。
abstract class はそのままではインスタンス化できず、不足しているメソッドを実装した派生クラスを用意して使用する。
記述例:
native
メソッドがJava言語以外で実装されていることを宣言する(Java Native Interfaceを参照)。
synchronized
メソッドの宣言や特定のブロックに付けられ、排他制御を指示する。同一オブジェクトが複数のオブジェクトから参照され、異なるスレッドで同時に処理を行っている場合でも、この修飾子があるブロックでは処理を行えるスレッドはただ1つしか存在しない。
記述例1:
記述例2:
記述例3:
volatile
フィールドの宣言に付けられ、キャッシュを見に行かずに常に最新の値を見に行くようになる。マルチスレッド下における軽量かつ限定的な同期処理に使われる。
例:
transient
フィールドの宣言につけられる。Javaにはオブジェクトをそのままネットワークに送信したりなどに保存したりするためのシリアライズと呼ばれる機能があり、transient は対象フィールドがシリアライズの対象にならないことを指示する。スレッドオブジェクトなど、保存できないフィールドや保存されると不都合なフィールドに対して使用される。
例外処理はC言語にはない。Javaでは、C++およびC#とほぼ共通の構文およびキーワードが使用されている。ただしfinallyはC++には存在せず、throwsはC#には存在しない。
try, catch, finally
例外が発生しうる箇所で使用する。tryブロック (try{と}との間) で例外が発生しうるコードを囲み、catchブロック (catch(java/langの派生クラス例外オブジェクト){と}との間) に例外発生後の処理を書く。finallyブロック (finally{と}との間) には、ファイルのクローズ、データベースセッションの切断、ログアウトなど、例外発生の有無にかかわらずtry/catchブロック内の処理を終了する前に必ず実行しておきたいコードを書く。catchを記述した場合finallyは省略可能であり、finallyを記述した場合catchは省略可能である。try/catchブロックとfinallyブロックの両方にreturn文がある場合、後者が優先される。catchブロックにはif-else-if文のように連続して捕捉したい例外を記述することができる。
throw
例外を発生させる。
throws
メソッドの宣言で使用される。そのメソッドがどのような例外をスローするかを列挙する。Javaにおける例外の種類には大きく分けて throws の明示が必要な例外と必要でない例外がある。前者は主にファイルエラーなどプログラムの動作中にその都度対応すべき例外で、後者は主に開発・デバッグの段階で対処すべき例外あるいは深刻なエラーである。
以下はjava/langを使った記述例である。
J2SE 1.4でassertが追加され、J2SE 5.0でenumが追加された。Java 9では制限されたキーワード (restricted keyword) として、open, module, requires, transitive, exports, opens, to, uses, provides, withが追加された。また、Java 9では単一のアンダースコア_が予約済みのキーワードとなり、識別子として使用できなくなった。
Java 10ではvarによる型推論が追加されたが、これはキーワードではなく、予約された型名 (reserved type name) によって実現されている。
その他のキーワードとして、浮動小数点演算の移植性を高めるstrictfpがある。浮動小数点の演算では一般に全く同じ結果は期待できないものではあるが、x87などハードウェアによっては、途中の値においてより高い精度や、より広い値の範囲で演算が行われるために、最終結果が他のプラットフォームと一致しない場合があり、特にIEEE 754を前提として予想される結果から外れることが問題である。
strictfpを指定すると、途中結果についても全てIEEE 754の倍精度を強制し、相異なるプラットフォーム同士の間でも演算結果が一致することを保証するとされている(仕様では FP-strict という用語を使っている)。Java VMの実装で、これを正しく実現するには、x86系CPUを使った計算機の場合、x87を避けてSSE2で計算するか、それができない場合は特殊なテクニックが必要である。
なお、同様に移植性のある結果を保証するjava/langというクラスがあるが、そちらはFDLIBMというSun製のライブラリと同じ結果を保証するとされている。
const、gotoがキーワードとして予約されているが、Javaでは使用できない。使用するとコンパイル時に構文エラーになる。