キーワード (Java)

この項目ではJavaにおけるキーワード（予約語の記事も参照）に関して説明する。Java 25現在、予約キーワード（reserved keyword）が51個、コンテキスト・キーワード（contextual keyword）が17個ある。

予約キーワードは識別子に用いることはできない。コンテキスト・キーワードは文脈に応じて識別子に用いることができたりできなかったりする。例えばコンテキスト・キーワードのopenはなどで識別子に用いられている。

この項目は、プログラムの細かい説明には立ち入らず、他の言語と比較できるような説明を目的としている。

 特徴 
プリミティブ型名や分岐処理 (if, switch)、反復処理 (for, while) などの基本的な構文とキーワードはC言語およびC++と共通するものが多い。クラスや例外処理に関してはC++類似の構文とキーワードが多い。

 沿革 
以下のキーワードが追加されている。
Java Language Specification First Edition のキーワードは47個。
J2SE 1.2でstrictfpが追加された。The Java Language Specification Second Edition
J2SE 1.4でassertが追加された。
J2SE 5.0でenumが追加された。
Java 9では制限付きキーワード (restricted keyword) として、open, module, requires, transitive, exports, opens, to, uses, provides, withが10個追加された。また、Java 9では単一のアンダースコア_がキーワードに追加され、識別子として使用できなくなった。
Java 10ではvarによる型推論が追加されたが、これはキーワードではなく、予約された型名 (reserved type name) によって実現されているJava 10リリース | InfoQ。
Java 14で追加された制限付き識別子（キーワードではない）のyieldは、switch式（JEP 361）で使用され、結果を返すために使用される。varが制限付き識別子に変更になった。
Java 16で追加された制限付き識別子（キーワードではない）のrecordは、データキャリアとして使用される不変のデータオブジェクトを簡単に定義するために導入された。
Java 17でキーワードが予約キーワードとコンテキスト・キーワードに分かれた。予約キーワードは従来のキーワードで識別子に使えない。Java 16まで制限付きキーワードと制限付き識別子と呼ばれていたものは統合されコンテキスト・キーワードに名称変更になり、文脈によってキーワードになる。コンテキスト・キーワードにnon-sealed, permits, sealedが3個追加された。
 sealedキーワードはクラスやインターフェースに対して使用され、指定されたサブクラスのみがクラスやインターフェースを拡張または実装できるようにする。
 permitsキーワードはsealedクラスの許可されたサブクラスを指定するために使用される。
 non-sealedキーワードはsealedクラスのサブクラスで、このサブクラスがさらに他のクラスによって拡張可能であることを示す。
 var, yield, recordが制限付き識別子からコンテキスト・キーワードに変更になった。
Java 21でJEP 441 (Pattern Matching for switch)からwhenがコンテキスト・キーワードに追加された。

 プリミティブ型 
 型名 
プリミティブ型の名前である。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）を保持するPrimitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)。
 void
 これはプリミティブ型ではないが、型と同じ文脈で使うキーワードなのでここに分類する。メソッドに戻り値がないことを宣言する。void (コンピュータ)も参照のこと。

 値（キーワードではない） 
以下はキーワードであるかのように扱われるが、キーワードではなく、定義では論理値リテラル、またはnullリテラルというリテラルである。
 true, false
 論理値を表すリテラル。
 null
 null型という特殊な型のリテラル。Nullも参照。

 モジュール 
モジュールでは以下のキーワードが使われている。
 module
 open
 opens
 exports
 provides
 requires
 to
 uses
 with
 transitive

 パッケージ 
 package
 自クラスのパッケージを宣言する。Javaではパッケージと呼ばれるツリー構造でクラス群を分類している。クラスやメンバに (後述する public, protected, private) を付けることにより、パッケージ内外でクラスやクラスのメンバにアクセス可能な範囲が変わってくる。
 import
 自クラスの所属するパッケージとは異なるパッケージにあるクラスを使用するときにこの宣言でインポートする。

 クラス 
 class
 クラスの定義。例えば、以下のように宣言する。それぞれについてはこの後、説明する。
例
 public class クラス名 { ... }
 public class クラス名 extends 親クラス名 { ... }
 public class クラス名 implements インタフェース名1, インタフェース名2, ... { ... }
 public class クラス名 extends 親クラス名 implements インタフェース名1, ... { ... }
 interface
 インタフェースの定義。Javaのインタフェースとは、定義のみで実装をもたない抽象型であり、型の多重継承に使用される。インタフェースのインスタンスを直接生成することはできない。サブクラスでインタフェースを実装して使用する。実装するインタフェースはカンマ区切りで複数並べることができる。
例
 public interface インタフェース名 { ... }
 public interface インタフェース名 extends 上位インタフェース名1, 上位インタフェース名2, ... { ... }
 extends
 class の宣言で他のクラスを継承するときに使用する。Javaのクラスは1つのスーパークラスのみ継承可能で、多重継承（実装の多重継承）はできない (参考: 菱形継承問題)。interfaceの宣言では一つ以上のインタフェースを継承するときに使用する。インタフェースがインタフェースを継承するだけなので、こちらの場合は多重継承が可能。
 implements
 class の宣言で、インタフェースを実装するときに使用する。カンマ区切りで並べた複数のインタフェースを実装することができる。
 enum
 列挙型
 this
 自クラスを明示するときに使用する。コンストラクタ内から他の引数のコンストラクタを呼ぶときに使用するのが一般的である。また、例えば、コンストラクタの場合はthis(引数)、メソッドの場合はthis.メソッド名(引数)などのように使い、親クラスに同一名・同一引数のメソッドがあるときに明示的に区別できるようにする。こちらは、ローカル変数や同じクラス内メソッドや上位クラスに同名のメソッドが存在しない場合はthisを省略できる。内部クラスのコード領域で外部クラスのインスタンスへの参照を得るときの構文（OuterClass.this）でも使用される。
 super
 上位クラスのコンストラクタ、フィールド、メソッドにアクセスするときに使用する。上位クラスのコンストラクタを呼び出すときは単にsuper(引数)と書き、メソッドを呼び出すときはsuper.メソッド名(引数)などのように使う。フィールドやメソッドの場合は、自クラスに同一のものがない場合はsuperの記述を省略できる。
 new
 コンストラクタの呼び出し。インスタンスを生成するときに使用する。
例
 SampleClass s = new SampleClass();
 int[] numbers = new int[5]; // int型の配列を生成
 List<String> list = new ArrayList<>(); // ジェネリッククラスのインスタンス化
 instanceof
 指定されたクラスのオブジェクトかどうか、あるいは指定されたインタフェースを実装しているオブジェクトかどうかを判定する。a instanceof ClassName とした場合、a が ClassName のオブジェクトか、その派生クラスのオブジェクトであれば true になる。ClassName の箇所にオブジェクトの変数名を記述することはできない。
 record
 record キーワードは、レコード型と呼ばれる新しい種類の型を定義するために使用される。レコード型は、従来のクラスと似ているが、いくつかの重要な違いがある。
 レコード型は、コンストラクタ、フィールド、アクセサメソッドを自動的に生成する。
 レコード型は、イミュータブル（変更不可）である。
 レコード型は、簡潔で読みやすいコードを作成するために使用できる。
例
record Person(String name, int age) {
  /* コンストラクタ、フィールド、アクセサメソッドは自動的に生成される */
}
 sealed
 sealed キーワードはクラスやインターフェースに対して使用され、指定されたサブクラスのみがクラスやインターフェースを拡張または実装できるようにする。これにより、クラス階層の管理が厳密に行えるようになる。
例
public sealed class Shape permits Circle, Square {
  // クラスの内容
}
 permits
 sealed クラスの許可されたサブクラスを指定するために使用される。
例
public sealed class Shape permits Circle, Square {
  // クラスの内容
}
 non-sealed
 sealed クラスのサブクラスで、このサブクラスがさらに他のクラスによって拡張可能であることを示す。
 non-sealed は単一の識別子ではなく、トークンシーケンスでコンテキスト・キーワードと呼ばれる。
例
public non-sealed class Circle extends Shape {
  // クラスの内容
}

 修飾子 
クラス、メンバの宣言に付けられる修飾子である。

 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:
public class SampleClass {
    final int constantValue = 5;
}

例2:
public class SampleClass {
    final int constantValue; // 初期化なし

    // コンストラクタ
    public SampleClass() {
        constantValue = 5;  // 1回だけ代入できる。
    }
}

 static
 フィールドに付けられた場合は、クラスに属する変数（クラス変数、静的フィールド、クラスフィールド）が確保されることを表す。この修飾子のついたフィールドは、インスタンスがいくつ生成されてもフィールドの実体は1つで、すべてのインスタンスの間で共有される。

記述例:
class SampleClass {
    static String shared = "shared";
    static final String STR = "constant";
}

 メソッドに付けられた場合は、オブジェクトを生成しなくても直接呼び出せるメソッド（静的メソッド、クラスメソッド）であることを表す。手続き型言語の関数と同じ扱いになる。

例:
class Sample1 {
    // static なメソッド
    public static void method() { ... }
}

class Sample2 {
    void proc() {
        ...
        Sample1.method(); // インスタンスを生成せず直接実行できる。
        ...
    }
}

 クラス内にstatic {...}というブロックが現れた場合は、そのクラスが最初に参照されたときにそのブロック内のコードを実行する。これを静的初期化子と呼び、主にstatic finalな配列やオブジェクトの初期化などに利用される。データベースにアクセスするためにJDBCドライバを呼び出すもこの静的初期化子を呼び出している。

例:
class StaticInitSampleClass {
    private static final List<String> list;

    static {
        final List<String> tempList = new ArrayList<>();
        tempList.add("Hello,");
        tempList.add("World.");
        StaticInitSampleClass.list = Collections.unmodifiableList(tempList);
    }
}

内部クラス
 入れ子にされたクラス（ネストされたクラス: nested class）のうち、static修飾されていないものは内部クラス (inner class) と呼ばれ、暗黙的に外側のクラスのインスタンスをキャプチャして参照することができるが、このネストクラスをstatic修飾すると静的ネストクラス (static nested class) となり、暗黙的に外側のクラスのインスタンスを参照できなくなるNested Classes (The Java™ Tutorials > Learning the Java Language > Classes and Objects)。

例:
class OuterClass {
    static int outerStaticField = 0;
    int outerField = 0;

    class InnerClass {
        void setOuterField(int value) {
            outerField = value; // 暗黙参照可能。
            outerStaticField = value; // OK。
        }
    }

    static class StaticClass {
        void setOuterField(int value) {
            //outerField = value; // コンパイルエラー。
            outerStaticField = value; // OK。
        }
    }

    public OuterClass() {
        new InnerClass().setOuterField(100);
        new StaticClass().setOuterField(-100);
    }

    public static void test() {
        final OuterClass outer = new OuterClass();
        System.out.println("OuterField = " + outer.outerField);
        System.out.println("OuterStaticField = " + outerStaticField);
    }
}

 abstract
クラスまたはメソッドに付けられる修飾子である。finalと併用することはできない。Javaでは、実装されないメソッドがあるクラスを作成することができる。抽象クラス自身のインスタンスを作成することはできない。似たものとしてインタフェースがあるが、abstract classは以下の点においてインタフェースと異なる。
 コンストラクタを持つことができる
 メソッドなどの実装を記述できる
 インスタンス変数を持つことができる
abstract classはそのままではインスタンス化できず、不足しているメソッドを実装した派生クラスを用意して使用する。

記述例:
public abstract class Sample {
    // 実装があるメソッド
    public void method1() {
        ...
    }
    // 実装がないメソッド
    public abstract void method2();
}

 native
 メソッドがJava言語以外で実装されていることを宣言する（Java Native Interfaceを参照）。
 synchronized
 メソッドの宣言や特定のブロックに付けられ、排他制御を指示する。同一オブジェクトが複数のオブジェクトから参照され、異なるスレッドで同時に処理を行っている場合でも、この修飾子があるブロックでは処理を行えるスレッドはただ1つしか存在しない。

記述例1:
public synchronized void method() { ... }

記述例2:
public void method() {
    ...
    synchronized(this) { // 自クラスのインスタンスに対して排他制御
        // 排他制御されるブロック
    }
    ...
}

記述例3:
public void method(Object obj) {
    ...
    synchronized(obj) { // Object obj に対して排他制御
        // 排他制御されるブロック
    }
    ...
}

 volatile
 フィールドの宣言に付けられ、キャッシュを見に行かずに常に最新の値を見に行くようになる。マルチスレッド下における軽量かつ限定的な同期処理に使われるJavaの理論と実践: volatile を扱う, Internet Archive。

例:
public class SampleClass {
    volatile int syncSample;
    ...
}

 transient
 フィールドの宣言につけられる。Javaにはオブジェクトをそのままネットワークに送信したりファイルなどに保存したりするためのシリアライズと呼ばれる機能があり、transientは対象フィールドがシリアライズの対象にならないことを指示する。スレッドオブジェクトなど、保存できないフィールドや保存されると不都合なフィールドに対して使用される。

 制御構造 
C言語およびC++と共通のキーワードを使用している。

 分岐
 if, else
 switch, case, when, default
 繰り返し
 for, while, do
 ジャンプ
 continue - ループの現在の反復 (iteration) をスキップするBranching Statements (The Java™ Tutorials > Learning the Java Language > Language Basics)
 break - ループのブロックから抜け出す
 return - メソッドから抜け出す。戻り値のあるものは値やオブジェクトの参照を返す。
 yield - switch式の値を返す。

 例外処理 
例外処理はC言語にはない。Javaでは、C++およびC#とほぼ共通の構文およびキーワードが使用されている。ただしfinallyはC++には存在せず、throwsはC#には存在しない。

 try, catch, finally
 例外が発生しうる箇所で使用する。tryブロック (try{と}との間) で例外が発生しうるコードを囲み、catchブロック (catch(の派生クラス例外オブジェクト){と}との間) に例外発生後の処理を書く。finallyブロック (finally{と}との間) には、ファイルのクローズ、データベースセッションの切断、ログアウトなど、例外発生の有無にかかわらずtry/catchブロック内の処理を終了する前に必ず実行しておきたいコードを書く。catchを記述した場合finallyは省略可能であり、finallyを記述した場合catchは省略可能である。try/catchブロックとfinallyブロックの両方にreturn文がある場合、後者が優先される。catchブロックにはif-else-if文のように連続して捕捉したい例外を記述することができる。
 throw
 例外を発生させる。
 throws
 メソッドの宣言で使用される。そのメソッドがどのような例外をスローするかを列挙する。Javaにおける例外の種類には大きく分けて
throwsの明示が必要なを継承していない例外
throwsの明示が必要でないを継承している例外
がある。前者は主にファイルエラーなどプログラムの動作中にその都度対応すべき例外で、後者は主に開発・デバッグの段階で対処すべき例外あるいは深刻なエラーである。

以下はを使った記述例である。
public void method() throws Exception { // メソッドが例外をスローすることを宣言
    try {
        ...
        if (エラー条件) {
            throw new IOException(); // 例外を発生させる。
        }
        // (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文が優先される。
        ...
    }
}

 assert 
 assert
 assert 違反時に  を投げる。

 型の省略 
 var
 ローカル変数およびラムダ式の引数で型を省略する際に var を使用する。Java 10以降で使用可能。

 変数名の省略 
 _
 変数名を省略する場合に使用する。Java 22以降で使用可能。

 浮動小数点演算 
浮動小数点演算の移植性を高めるstrictfpがある。浮動小数点の演算では一般に全く同じ結果は期待できないものではあるが、x87などハードウェアによっては、途中の値においてより高い精度や、より広い値の範囲で演算が行われるために、最終結果が他のプラットフォームと一致しない場合があり、特にIEEE 754を前提として予想される結果から外れることが問題である。

strictfpを指定すると、途中結果についても全てIEEE 754の倍精度を強制し、相異なるプラットフォーム同士の間でも演算結果が一致することを保証するとされている（仕様では FP-strict という用語を使っている）。Java VMの実装で、これを正しく実現するには、x86系CPUを使った計算機の場合、x87を避けてSSE2で計算するか、それができない場合は特殊なテクニックオライリー『Binary Hacks』Hack #98 を参照。が必要である。

なお、同様に移植性のある結果を保証するというクラスがあるが、そちらはFDLIBMというSun製のライブラリと同じ結果を保証するとされている。

Java 17以降は常にstrictfpを付けたときの挙動と同じになった。x86系CPUでは常にSSE2以降を使用して計算する。

 未使用 
const、gotoがキーワードとして予約されているが、Javaでは使用できない。使用するとコンパイル時に構文エラーになる。

 脚注 

 注釈 

 出典 

 参考文献 

きわと (Javaけんこ)
きわと
Java