----
本書は初級から上級までを網羅し、Javaの基礎から応用までをカバーします。
初級編では基本文法や概念、中級編ではオブジェクト指向やスレッド処理、上級編ではリフレクションやデータベース連携、GUIやWebアプリケーション開発、さらにフレームワークの利用方法まで学べます。
本書は幅広い読者に価値を提供し、Javaプログラミングのスキル向上を支援します。
Java入門
基本文法と概念
オブジェクト指向プログラミング (OOP)
スレッドと並行処理
ラムダ式とストリームAPI
デザインパターン
特殊機能と技術
リフレクション
ユニットテスト
データベース連携
GUIアプリケーション開発
Webアプリケーション開発
フレームワーク
Spring Framework -- 総合アプリケーションフレームワーク。
Google Guice -- 軽量な依存性注入（DI）フレームワーク。
Google Guava -- コレクションフレームワークを含んだユーティリティライブラリ。
(Apache Commons Lang) -- 総称型に非対応、多くの機能は Java SE が実装。
Java 17 (2021年9月):
SealedClass: sealedキーワードを使用して定義され、特定のサブクラスを許可するように指定されます。サブクラスは、permitsキーワードを使用して封印されたクラス内で明示的に指定されなければなりません。
スイッチ式のパターンマッチング）: switch文内で条件に基づいてパターンを指定し分岐を実現します。パターンには型、値、nullチェックなどが含まれ、複雑な条件を直感的に表現できます。
フィーチャーサポート: 長期サポートリリース（LTS）としてのJava 17のサポートが追加され、将来の安定性と互換性が保証されました。
Java 16 (2021年3月):
record: recordは不変性を持ち、自動的にequals()、hashCode()、toString()メソッドを生成し、フィールドを読み取り専用にすることができます。
instanceofのパターンマッチング: 新しいinstanceof演算子が導入され、型パターンのチェックが可能になりました。
UNIXドメインソケット: UNIXドメインソケットのサポートが追加され、ローカル通信を可能にしました。
OpenJDKポリシーの変更: OpenJDKのライセンスポリシーが変更され、将来のバージョンに対するサポートが改善されました。
Java 15 (2020年9月):
テキストブロックの改善: テキストブロックが改善され、エスケープシーケンスの処理が改善されました。
Java 14 (2020年3月):
ジャヴァフライトレコーダ: Java Flight Recorder（JFR）がオープンソース化され、広範なプロファイリングツールが提供されました。
Java 13 (2019年9月):
テキストブロック: 複数行の文字列リテラルのためのテキストブロック機能が導入され、文字列の可読性が向上しました。
Java 12 (2019年3月):
switch式: 新しいswitch式が導入され、より簡潔なコード記述が可能になりました。
Java 11 (2018年9月):
ローカル変数の構文拡張: varキーワードをローカル変数の宣言だけでなく、foreachループのインデックス宣言でも使用できるようになりました。
Java 10 (2018年3月):
var型: ローカル変数の型推論を導入し、varキーワードを使用して変数を宣言することができるようになりました。
ローカル変数の型推論: メソッドのパラメーターにおいて、型の明示的な宣言を省略できるようになりました。
Java 9 (2017年9月):
モジュラーシステム: モジュールシステム（Project Jigsaw）が追加され、アプリケーションをモジュールに分割し、依存関係を明示的に定義できるようになりました。
JShell: 対話型のJavaシェル（REPL）が追加され、Javaのコード断片を即座に試行できるようになりました。
プライベートメソッドインターフェース: インターフェース内でプライベートメソッドとプライベートスタティックメソッドを定義できるようになりました。
Java 8 (2014年3月):
ラムダ式とストリームAPI: ラムダ式を導入し、コードの簡潔化とストリーム処理をサポートするStream APIが追加されました。
Optional: nullを扱うための新しいクラスOptionalが導入され、nullポインタ例外の回避をサポートします。
Date/Time API: Joda-Timeにインスパイアされた新しい日付と時間のAPIが導入されました。
Java 7 (2011年7月):
文字列スイッチ: switch文で文字列の比較をサポートしました。
ダイヤモンド演算子: ジェネリックのインスタンス化時に型を省略できるようになりました。
Try-with-resources: try文でのリソースの自動クローズをサポートするための新しい構文が導入されました。
アンダースコア: 数値リテラルにおいて、読みやすさを向上させるために、桁区切りに使用されます。
ジェネリック例外の型推論：Java 7.0では、catchブロックでジェネリック例外をキャッチするときに、ジェネリック型の推論ができるようになりました。
可変長引数の改善：可変長引数を使用して、他の引数と組み合わせて使用できるようになりました。
インスタンス化されたジェネリック型の引数の型推論：コンパイラが、ジェネリック型の引数の型を自動的に推論できるようになりました。
Java 6 (2006年12月):
コンパイル時定数（Compile-Time Constants）：Java 6.0では、定数式が宣言された場所で評価されるようになりました。これにより、実行時のコストが削減され、コードの簡潔性が向上しました。
リテラル文字列の自動的な連結（Automatic Concatenation of Literal Strings）：Java 6.0では、複数のリテラル文字列が隣接している場合、自動的に連結されるようになりました。これにより、コードの可読性が向上し、記述の簡略化が可能になりました。
Java 5 (2004年9月):
ジェネリクス: 型安全性を向上させるためのジェネリックスが導入されました。
拡張forループ（Enhanced For Loop）: コレクションや配列を簡潔に処理するための拡張forループが導入されました。
オートボクシングとアンボクシング: プリミティブ型とそれに対応するラッパークラスの間で自動的に変換が行われるようになりました。
アノテーション: クラス、メソッド、変数などに付与することができるメタデータで、コンパイル時や実行時に利用される。
列挙型: 列挙型は、定数の集合を表現するために使用されます。列挙型は、コンパイル時の型検査に役立ちます。
静的インポート: 静的メンバーをインポートすることができます。
可変長引数: メソッドが可変数の引数を取ることができるようになります。
Javaの歴史は1980年代後半に始まります。当初、サン・マイクロシステムズ（後のサン・マイクロシステムズ、現在のオラクル）は、組み込みシステム向けの言語として「Oak」と呼ばれるプロジェクトを開始しました。その後、1995年に「Java」として発表され、ウェブアプリケーションやインターネット上の動的なコンテンツを可能にする目的で設計されました。
Javaは初めはブラウザ上でアプレットとして実行され、クロスプラットフォーム対応とセキュリティに焦点を当てていました。その後、Javaはサーバーサイドアプリケーションや企業システムの開発にも広く採用されました。1998年にはJavaの最初の大規模なアップデートであるJava 2がリリースされました。
2006年にはサン・マイクロシステムズがJavaをオープンソース化し、Java Community Process（JCP）を通じて開発者コミュニティによる標準化プロセスを導入しました。これにより、Javaの進化はより広範囲の開発者によって促進されました。
2010年代には、Oracle Corporationがサン・マイクロシステムズを買収し、Javaの開発とサポートを引き継ぎました。Java 8では、ラムダ式やストリームAPIなどの新機能が追加され、言語とライブラリの改善が行われました。
その後、Java 9以降のバージョンでは、モジュールシステムやリアクティブプログラミングのサポートなど、さまざまな新機能が導入されました。Javaは、現在も広範囲にわたるアプリケーション開発において重要な役割を果たし続けています。
import java.util.*;
public class Main {
    public static void eratosthenes(int n) {
        boolean[] sieve = new boolean[n + 1];
        sieve[0] = false;
        sieve[1] = false;
        for (int i = 2; i <= n; i++) {
            sieve[i] = true;
        }
        for (int i = 2; i <= n; i++) {
            if (sieve[i]) {
                System.out.println(i);
                for (int j = i * 2; j <= n; j += i) {
                    sieve[j] = false;
                }
            }
        }
    }
    public static void main(String[] args) {
        eratosthenes(100);
    }
}
このJavaのコードは、エラトステネスの篩（Sieve of Eratosthenes）アルゴリズムを使って、与えられた範囲内の素数を見つけて出力します。
n 以下の素数を見つけるために、boolean配列 sieve を用意します。sieve[i] が true の場合、i は素数です。
初期化の際、sieve[0] と sieve[1] を false に設定し、それ以外の要素を true に初期化します。
2から n までの各数に対して、その数が素数である場合、その数を出力し、その倍数を false にマークします。
mainメソッドでは、eratosthenesメソッドを呼び出して、100 以下の素数を見つけて出力します。
具体的には、eratosthenesメソッドは次の手順で動作します：
n 以下の数を true に初期化します。
2から n までの各数について、その数が素数である場合、その数自体を出力し、その数の倍数を false にします。これにより、残った true の数は素数になります。
例えば、eratosthenes(100) を実行すると、100 以下の素数が出力されます。
import java.util.Arrays;
public class Main {
    public static int gcd2(int m, int n) {
        return n == 0 ? m : gcd2(n, m % n);
    }
    public static int gcd(int... ints) {
        if (ints.length == 0) {
            throw new IllegalArgumentException("At least one argument is required");
        }
        return Arrays.stream(ints).reduce(Main::gcd2).getAsInt();
    }
    public static int lcm2(int m, int n) {
        return m * n / gcd2(m, n);
    }
    public static int lcm(int... ints) {
        if (ints.length == 0) {
            throw new IllegalArgumentException("At least one argument is required");
        }
        return Arrays.stream(ints).reduce(Main::lcm2).getAsInt();
    }
    public static void main(String[] args) {
        System.out.println("gcd2(30, 45) => " + gcd2(30, 45));
        System.out.println("gcd(30, 72, 12) => " + gcd(30, 72, 12));
        System.out.println("lcm2(30, 72) => " + lcm2(30, 72));
        System.out.println("lcm(30, 42, 72) => " + lcm(30, 42, 72));
    }
}
このコードは、最大公約数（Greatest Common Divisor, GCD）と最小公倍数（Least Common Multiple, LCM）を計算するための関数を実装しています。
gcdおよびlcmメソッド内のreduceメソッド:
Arrays.stream(ints)を使用してintsをストリームに変換し、reduceメソッドを使ってMain::gcd2またはMain::lcm2関数を累積的に適用します。
getAsInt()メソッドを使用して結果を取得します。これは、OptionalIntをintに変換する操作です。getAsInt()はストリームが空でないことを前提としていますが、この場合は引数が少なくとも1つ以上あることが保証されているため問題ありません。
二分法
import java.util.function.Function;
public class Main {
    public static double bisection(double low, double high, Function f) {
        double x = (low + high) / 2;
        double fx = f.apply(x);
        final double epsilon = 1.0e-10;
        if (Math.abs(fx) < epsilon) {
            return x;
        }
        if (fx < 0.0) {
            low = x;
        } else {
            high = x;
        }
        return bisection(low, high, f);
    }
    public static void main(String[] args) {
        var result1 = bisection(0, 3, x -> x - 1);
        System.out.println(result1);
        var result2 = bisection(0, 3, x -> x * x - 1);
        System.out.println(result2);
    }
}
旧課程(-2012年度)高等学校数学B/数値計算とコンピューター#2分法の例を Java に移植しました。
このJavaのコードは、二分法（Bisection Method）を使って与えられた関数の根（解）を求める方法を示しています。
与えられた範囲 low から high の間で関数 f の根を見つけるメソッドです。
low と high の中間点を x として計算し、その点での関数値 fx を取得します。
fx の絶対値が非常に小さい（この場合、1.0e-10より小さい）場合、x を見つけたとみなして返します。
それ以外の場合、fx の符号をチェックして、x を新しい範囲の中心として、low または high を更新し、再帰的に bisection メソッドを呼び出します。
mainメソッドでは、bisectionメソッドを使用して、与えられた関数の根を求めます。
例えば、x - 1 の関数の根を 0 から 3 の範囲で見つけて出力し、x^2 - 1 の関数の根を同様に見つけて出力します。
このコードは、JavaのFunctionインターフェースを利用して、関数を引数として渡し、二分法を使って関数の根を見つける方法を実装しています。
abstract（抽象）: インスタンスを作成できない抽象クラスや抽象メソッドを定義するための修飾子。
annotation（アノテーション）: ソースコードにメタデータを追加するための機能。
Array（配列）: 同じ型の複数の要素を保持するためのデータ構造。
ArrayList（動的配列）: 可変長配列を実現するためのクラス。
assert（アサート）: 条件が正しいことをチェックするために使用されるキーワード。
binary operator（二項演算子）: 2つのオペランドを持つ演算子。
boolean（論理値）: 2つの値、trueまたはfalse、を持つデータ型。
break（ブレーク）: ループやswitch文から抜け出すためのキーワード。
byte（バイト）: 8ビットの符号付整数型のデータ型。
case（ケース）: switch文内で、評価式の値と一致する場合に実行されるブロック。
catch（キャッチ）: tryブロック内で発生した例外を処理するためのブロック。
char（文字）: 16ビットUnicode文字のデータ型。
class（クラス）: データとその操作を定義するための構造体。
class variable（クラス変数）: クラスのすべてのインスタンスで共有される変数。
compiler（コンパイラ）: ソースコードを機械語に変換するプログラム。
constructor（コンストラクタ）: オブジェクトを作成する際に呼び出されるメソッド。
continue（コンティニュー）: ループ内で次の反復処理に進むためのキーワード。
do-while（do-while文）: 条件式がfalseでない限り、ブロックを実行し続けるループ。
double（倍精度浮動小数点数）: 64ビットの浮動小数点数のデータ型。
encapsulation（カプセル化）: データとそれに対する操作をまとめ、外部からのアクセスを制限する機能。
enhanced for loop（拡張forループ）: 配列やコレクションの要素に対して繰り返し処理を行うための簡潔な構文。
enum（列挙型）: 一連の定数を表すための特殊なクラス。
exception（例外）: プログラムの実行中に発生するエラーを表すオブジェクト。
extends（継承）:クラスの継承に使用されるJavaのキーワード。
final（最終）:フィールド、メソッド、またはクラスに修飾子として付けられ、値の変更やオーバーライドを禁止する。
finally（最後に）:例外処理ブロックの一部で、必ず実行されるコードを指定するために使用されるキーワード。
float（浮動小数点数）:単精度浮動小数点数を表すJavaのプリミティブ型。
for（forループ）:指定された回数または条件に基づいて、コードブロックを反復的に実行するために使用されるキーワード。
foreach（拡張forループ）:配列またはコレクションに対して、簡単な反復処理を行うために使用されるJavaの構文。
generic（ジェネリック）:クラスやメソッドにパラメーターを追加し、異なるデータ型のオブジェクトを扱う汎用的なプログラミングの機能。
getter（ゲッター）:クラスのインスタンス変数の値を取得するためのメソッド。
if-else（条件分岐）:条件が真の場合に1つのコードブロックを実行し、そうでない場合に別のコードブロックを実行するために使用されるJavaの構文。
implements（実装）:インターフェイスを実装するクラスに使用されるキーワード。
import（インポート）:別のパッケージ内のクラスを使用するために、Javaに外部クラスを取り込むためのキーワード。
instance variable（インスタンス変数）:クラスのインスタンスの一部であり、オブジェクトの特定の状態を保持するために使用される変数。
int（整数）:32ビットの整数を表すJavaのプリミティブ型。
interface（インターフェイス）:クラスのメソッドの集合であり、実装クラスによって実装されることを想定している。
jar（JARファイル）:Javaアプリケーションをパッケージ化するための標準的な形式のアーカイブファイル。
java keyword（Javaのキーワード）:Javaの構文で特別な意味を持つ予約語。
java runtime environment(JRE): Javaアプリケーションを実行するためのランタイム環境。
JDK: Java開発キット。Java開発に必要なツール、コンパイラ、デバッガ、API、ドキュメントが含まれる。
JRE: Javaランタイム環境。Javaアプリケーションを実行するための環境。
JVM: Java仮想マシン。Javaアプリケーションを実行するための仮想コンピュータ。
lambda expression: Java 8で導入された無名関数の一種。
long: Javaのデータ型の一つで、64ビットの符号付き整数を表す。
method: クラス内で実行されるコードブロックのこと。
modifier: クラス、メソッド、変数などの属性を変更するために使用されるキーワード。
new: オブジェクトのインスタンスを作成するためのキーワード。
null: オブジェクトが存在しないことを示す値。
NumberFormatException: 文字列を数値に変換しようとした際に、文字列が数値に変換できない場合にスローされる例外。
object: データやメソッドを持つインスタンス。
Object-Oriented Programming: オブジェクト指向プログラミング。クラス、オブジェクト、継承、ポリモーフィズムなどを利用してプログラムを設計する方法。
operator: 演算子。算術演算子、比較演算子、論理演算子などがある。
package: クラスやインターフェースをグループ化するための仕組み。
private: クラスの外部からアクセスできないアクセス修飾子。
protected: サブクラスからのみアクセス可能なアクセス修飾子。
public: 全てのクラスからアクセス可能なアクセス修飾子。
return: メソッドから値を返すために使用されるキーワード。
short: Javaのデータ型の一つで、16ビットの符号付き整数を表す。
static: クラスレベルの変数やメソッドに使用される修飾子。
String: 文字列を表すクラス。
super: スーパークラスのインスタンスを参照するためのキーワード。
switch: 複数の条件分岐をまとめて表現するためのキーワード。
synchronized: (同期化) スレッド間で共有されるオブジェクトに対して、1つのスレッドが実行しているときは、他のスレッドが同時にそのオブジェクトにアクセスできないようにするためのキーワードです。
this: (this) オブジェクト自身を参照するためのキーワードです。
throw: (例外を投げる) メソッド内で明示的に例外を投げるために使用されるキーワードです。
throws: (例外をスローする) メソッドが例外を投げる可能性があることを示すために使用されるキーワードです。
transient: (一時的) シリアル化されたオブジェクトの一部でないことを示すために使用されるキーワードです。
try-catch: (例外処理) 例外が発生する可能性があるブロック内で、例外を捕捉して処理するための構文です。
void: (無効) 戻り値を返さないメソッドを定義するためのキーワードです。
volatile: (揮発性) 変数の値が、複数のスレッドから同時にアクセスされる可能性があることを示すために使用されるキーワードです。
while: (ループ) 条件が true の場合、ブロックを繰り返し実行するためのループ構文です。