「キーワード (Java)」の版間の差分
(相違点なし)
|
2014年3月14日 (金) 16:43時点における最新版
この項目ではJavaにおけるキーワード(予約語の記事を参照)[1]に関して説明する。全部で50個ある。
この項目は、プログラムの細かい説明には立ち入らず、他の言語と比較できるような説明を目的としている。
目次
特徴
プリミティブ型
型名
プリミティブ型の名前である。C言語と共通するものが多い。
- byte, char, short, int, long, float, double
- boolean
- void
- これはプリミティブ型ではないが、型と同じ文脈で使うキーワードなのでここに分類する。メソッドに戻り値がないことを宣言する。void (コンピュータ)も参照のこと。
値
以下はキーワードと同様に扱われるが、定義では論理値リテラル、またはnullリテラルというリテラルである。
制御構造
C言語と共通のキーワードを使用している。
- 分岐
- if, else
- switch, case, default
- 繰り返し
- for, while, do
- ジャンプ
- continue - ループの先頭に戻る
- break - ループのブロックから抜け出す
- return - メソッドから抜け出す。戻り値のあるものは値やオブジェクトの参照を返す。
クラス、パッケージ
- package
- import
- 自クラスの所属するパッケージとは異なるパッケージにあるクラスを使用するときにこの宣言でインポートする。
- class
- クラスの定義。例えば、以下のように宣言する。それぞれについてはこの後、説明する。
例1 public class クラス名 { ... } 例2 public class クラス名 extends 親クラス名 { ... } 例3 public class クラス名 implements インタフェース名1,インタフェース名2, ... { ... } 例4 public class クラス名 extends 親クラス名 implements インタフェース名1, ... { ... }
- interface
例1 public interface インタフェース名 { ... } 例2 public interface インタフェース名 extends 上位インタフェース名1, 上位インタフェース名2, ... { ... }
- extends
- class の宣言で他のクラスを継承するときに使用する。Javaでは1つのクラスのみ継承可能で多重継承はできない。interfaceの宣言では複数のインタフェースを継承するときに使用する。インタフェースがインタフェースを継承するだけなので、こちらの場合は多重継承が可能。
- implements
- class の宣言で、インタフェースを実装するときに使用する。こちらは複数のインタフェースをカンマ区切りで実装することができる。
- this
- super
- new
- コンストラクタの呼び出し。オブジェクトを生成するときに使用する。
例: Sample s = new Sample()
- instanceof
- 指定されたクラスのオブジェクトかどうかを判定する。a instanceof (クラス名) とした場合、a が (クラス名) のオブジェクトか、その下位クラスのオブジェクトであれば true になる。(クラス名) のところにオブジェクトの変数名を記述することはできない。
修飾子
クラス、メンバの宣言に付けられる修飾子である。
- public, protected, private
- クラス、メンバのアクセス制御を指示する修飾子である。外部からアクセス可能な範囲を決める。Javaでは4つの段階が設けられ、番号が大きくなるほど外部からのアクセスが制約される。
- public では、すべてのクラスから見える(アクセス可能である)。
- protected では、同一パッケージにあるクラスかサブクラスからのみ見える。異なるパッケージでサブクラスでないクラスからはアクセスできない。クラスを修飾することはできない(内部クラスは例外)。
- アクセス制御の修飾子がない場合は、同一のパッケージ内のクラスからのみ見える。サブクラスであってもパッケージが異なる場合はアクセスできない。
- private では、自クラス内でのみ見える。外部からはアクセスできない。クラスに修飾することはできない(内部クラスは例外)。
- Java SE1.0ではprivate protectedという組み合わせを使用して、自分自身とサブクラスからのアクセスができたが同じパッケージ内の他のクラスからはアクセスできないというアクセス権を使用することができたが、これはJava SE 1.1以降から廃止され利用することができなくなった。
- クラス、メンバのアクセス制御を指示する修飾子である。外部からアクセス可能な範囲を決める。Javaでは4つの段階が設けられ、番号が大きくなるほど外部からのアクセスが制約される。
- final
- フィールドに付けられた場合は定数であることを表す。メソッド宣言に付けられた場合は、下位クラスで上書きできないことを表す。クラス宣言に付けられた場合は、継承できないことを表す。なお、Javaでは、final宣言されたフィールドで、宣言部では初期化せずコンストラクタ内で1回だけ代入できる記述も行える。abstractとの併用はできない。メソッドの引数やローカル変数に使用すればその引数やローカル変数を変更できない定数とした堅牢性の高いメソッドを作ることができる。final修飾子は「イミュータブル(不変)」なクラスを実装するときに役立つ。
例1 final int constantvalue = 5;
例2 final int constantvalue; //初期化なし ... public Sample(){ //コンストラクタ constantvalue = 5; //1回だけ代入できる。 }
- static
- フィールドに付けられた場合は、クラスに属する変数が確保されることを表す。クラスにつけることはできない(内部クラスは例外)。この修飾子のついたフィールドは、オブジェクトがいくつも生成されてもフィールドの実態は1つで、すべてのオブジェクトから共有される。
記述例: static final String STR = "constant";
例 public class Sample1 { public static void method{...} //static なメソッド } public class Sample2 { void proc(){ ... Sample1.method(); //インスタンスを生成せず直接実行できる。 ... } }
- static {...}というブロックが現れた場合は、そのクラスを最初に呼び出されたときにそのブロック内のコードを実行する。これは静的初期化子と呼び、主にstatic finalな配列やテンプレート:Javadoc:SEオブジェクトの初期化などに利用される。データベースにアクセスするためにJDBCドライバを呼び出すテンプレート:Javadoc:SEもこの静的初期化子を呼び出している。
例 public class StaticSample { private static final List<String> list; static{ List<String> tempList = new ArrayList<>(); tempList = new ArrayList<>(); tempList.add("Hello,"); tempList.add("World."); StaticSample.list = Collections.unmodifiableList(tempList); } }
- abstract
- 抽象クラスまたは実装のないメソッドに付けられる修飾子である。finalと併用することはできない。Javaでは、実装されないメソッドがあるクラスを作成することができる。抽象クラスのインスタンスを作成することはできない。似たものとしてインターフェイスがあるが、abstract class では、1) コンストラクタを持つことができる点、2) メソッドなどの実装が記述ができる点 3) インスタンス変数を持つことができる点が異なる。abstract class はそのままでは使用できず、下位クラスで不足しているメソッドを実装したクラスを用意して使用する。
記述例: public abstract class Sample { public void method1(){ //実装のある記述 } public abstract void method2(); //実装がないメソッド }
- native
- メソッドがJava言語以外で実装されていることを宣言する。
- synchronized
記述例:1 public synchronized void method(){...}
記述例:2 public void method(){ ... synchronized(this){ //自クラスのインスタンスに対して排他制御 //排他制御されるブロック } ... }
記述例:3 public void method(Object o){ ... synchronized(o){ //Object o に対して排他制御 //排他制御されるブロック } ... }
- volatile
- フィールドの宣言に付けられ、キャッシュを見に行かずに、常に最新の値を見に行くようになる。マルチスレッド下における同期処理に使われる。
例 public class Sample { volatile int syncSample; ... }
- transient
例外処理
例外処理はC言語にはない。C++ではほぼ共通のキーワードが使用されている。 但しfinallyはC++には存在せず、throwsもC#には存在しない。
- try, catch, finally
- 例外が発生しうる箇所で使用する。tryブロック(
try{
と}
との間)で例外が発生しうるコードを囲み、catchブロック(catch(テンプレート:Javadoc:SEの下位クラス例外オブジェクト){
と}
との間)に例外発生後の処理を書く。finallyブロック(finally{
と}
との間)には、ファイルのクローズ、データベースセッションの切断、ログアウトなど、例外発生の有無にかかわらずtry/catchブロック内の処理を終了する前に必ず実行しておきたいコードを書く。catchを記述した場合finallyは省略可能であり、finallyを記述した場合catchは省略可能である。try/catchブロックとfinallyブロックの両方にreturn文がある場合、後者が優先される。catchブロックにはif-else-if文のように連続して捕捉したい例外を記述することができる。ただし、例外記述順序は最初に具象例外クラスを記述し、徐々に抽象化してゆき、最後にテンプレート:Javadoc:SEクラスを記述するようにすべきである。先に抽象的な例外クラスを記述すると、その下位クラスもそこで捕捉されてしまうからである。
- 例外が発生しうる箇所で使用する。tryブロック(
- throw
- 例外を発生させる。
- throws
- メソッドの宣言で使用される。そのメソッドがどのような例外をスローするかを列挙する。Javaにおける例外の種類には大きく分けて throws の明示が必要な例外と記述を省略可能な例外がある。前者は主にファイルエラーなどプログラムの動作中にその都度対応すべき例外で、後者は主に開発・デバッグの段階で対処すべき例外あるいは深刻なエラーである。
記述例: public void method() throws Exception{ // 例外をスローすることを宣言 try { ... if (err) throw new テンプレート:Javadoc:SE(); //例外を発生させる。 //1) 正常終了 //このtryブロックにはreturn文を記述することもできる。 //但し、finallyブロックにすでにreturn文があるときは //ここにreturn文を書いてもfinallyブロックのreturnが優先される。 } catch(IOException e) { // IOException は Java の例外クラスの1つ //2) 例外処理 //このcatchブロックにはreturn文を記述することもできる。 //但し、finallyブロックにすでにreturn文があるときは //ここにreturn文を書いてもfinallyブロックのreturnが優先される。 } catch(Exception e) { //IOException よりも上位(親)の例外クラス //3) 例外をさらに外のブロックにスローする。 throw e; } finally { //例外発生の有無にかかわらず、1) 2) 3) どの場合でもこのブロックは //必ず処理される。ここにreturn文があるときはtry/catchブロックにも //return文があろうともこちらのreturn文が優先される。 ... } }
追加されたキーワード
J2SE 1.4でassertが追加され、J2SE 5.0でenumが追加された。
その他
浮動小数点演算
その他のキーワードとして、浮動小数点演算の移植性を高めるstrictfpがある。浮動小数点の演算では一般に全く同じ結果は期待できないものではあるが、x87などハードウェアによっては、途中の値においてより高い精度や、より広い値の範囲で演算が行われるために、最終結果が他のプラットフォームと一致しない場合があり、特にIEEE 754を前提として予想される結果から外れることが問題である。
strictfpを指定すると、途中結果についても全てIEEE 754の倍精度を強制し、相異なるプラットフォーム同士の間でも演算結果が一致することを保証するとされている(仕様では FP-strict という用語を使っている[2])。Java VMの実装で、これを正しく実現するには、x86系CPUを使った計算機の場合、x87を避けてSSE2で計算するか、それができない場合は特殊なテクニック[3]が必要である。
なお、同様に移植性のある結果を保証するテンプレート:Javadoc:SEというクラスがあるが、そちらはFDLIBMというSun製のライブラリと同じ結果を保証するとされている。
未使用
const, goto がキーワードとして予約されているが、Javaでは使用できない。使用するとコンパイル時に構文エラーになる。
注
- ↑ 仕様において reserved word ではなく keyword と呼んでいる。 [1] を参照
- ↑ http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.4
- ↑ オライリー『Binary Hacks』Hack #98 を見よ。