ProgrammingJava開発者

Javaにおけるrecordクラスとは何か、その目的と制限は何か?

Hintsage AIアシスタントで面接を突破

回答。

問題の歴史:

recordクラスはJava 14でプレビューとして登場し、Java 16では安定した機能として実装されています。これは、値オブジェクトに似た不変(immutable)データコンテナの概念を実現しています。これは、Javaにおける従来のDTOやPOJOの冗長さに対する反応です。

問題:

データを持つシンプルなオブジェクトに対して、コンストラクター、equals()、hashCode()、toString()を手動で実装する必要がありました。これは、エラーが発生しやすいルーチンで、多くの行のコードを消費します。

解決策:

recordクラスは1行で宣言され、自動的にコンストラクター、ゲッター、equals()、hashCode()、toString()を取得します。recordのフィールドは不変(final)であり、特にアプリケーションの層間で情報を渡すのに便利です。

コード例:

public record Point(int x, int y) {} Point p = new Point(3, 5); System.out.println(p.x()); // 3 System.out.println(p); // Point[x=3, y=5]

主な特徴:

  • 不変性:フィールドはfinalであり、値はコンストラクターを通じてのみ設定されます。
  • 標準メソッドの自動生成。
  • 他のクラスから継承できない(Objectを除く);インターフェースは実装可能です。

trick questions.

recordオブジェクトの生成後に状態を変更できますか?

いいえ – すべてのフィールドはfinalであり、いかなる方法でも値を変更することはできません。

コンストラクター内で非標準のロジックを持つrecordを作成できますか?

はい、コンパクトまたは通常のコンストラクターを定義し、チェックを追加できます:

public record Point(int x, int y) { public Point { if (x < 0 || y < 0) throw new IllegalArgumentException(); } }

recordは抽象的にできますか、それとも他のクラスのフィールド/ロジックを継承できますか?

いいえ – recordは常にfinalです。インターフェースを実装することはできますが、クラスを継承することはできません(Objectを除く)。

一般的なエラーとアンチパターン

  • フィールドを変更可能にしようとする – 構文がそれを許可しません。
  • record内部で複雑なロジックを作成し、「データコンテナ」というシンプルなアイデアを破る。
  • 振る舞いを必要とする通常のクラスが必要な場所でrecordを使用する。

実際の例

ネガティブケース

各リクエスト/レスポンスのための長いPOJOの使用、equals、hashCode、toString、コンストラクターとゲッターを手動で記述。

利点:

  • 実装の完全な柔軟性。

欠点:

  • コード量が多い。
  • エラーが発生するリスクが高い。

ポジティブケース

全てのDTOをrecordクラスに変換:

public record UserDTO(String login, String email) {}

利点:

  • コードが最小限。
  • 自動的に正しいequals/hashCode。
  • 実装で間違子ことは困難。

欠点:

  • 変更可能なオブジェクトや特定のロジックが必要な場合、recordは適していません。