Java ジェネリックのこれらの文字は何を意味するのでしょうか? (E、T、K、V、S)
ジェネリッククラス、ジェネリックインターフェイス、ジェネリックメソッドを詳しく解説!
クラス、インターフェイス、またはメソッドを定義するときに、型パラメーター (型パラメーター) を使用して未知の型を表すことができ、コードをより一般的かつ柔軟にすることができます。クラス、インターフェイス、メソッドの例を以下に示します。
1. クラスで型パラメータを使用します。
public class Box<T> {
private T value;
public Box(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
この例では、Box
クラスは型パラメーターを使用してT
不明な型を表し、具体的な型はオブジェクトの作成時に指定できます。たとえば、Box
整数型の値を格納するオブジェクトを作成できます。
Box<Integer> integerBox = new Box<>(10);
Integer value = integerBox.getValue(); // 获取整数值
文字列型の値を保存するオブジェクトを作成することもできますBox
。
Box<String> stringBox = new Box<>("Hello");
String value = stringBox.getValue(); // 获取字符串值
2. インターフェイスで型パラメータを使用します。
public interface List<T> {
void add(T element);
T get(int index);
}
この例では、List
インターフェイスは型パラメーターを使用してT
未知の型を表しており、インターフェイスの実装時に具体的な型を指定できます。たとえば、整数のリストは次のように実装できます。
public class IntegerList implements List<Integer> {
private List<Integer> elements = new ArrayList<>();
@Override
public void add(Integer element) {
elements.add(element);
}
@Override
public Integer get(int index) {
return elements.get(index);
}
}
文字列のリストも実装できます。
public class StringList implements List<String> {
private List<String> elements = new ArrayList<>();
@Override
public void add(String element) {
elements.add(element);
}
@Override
public String get(int index) {
return elements.get(index);
}
}
3. メソッドで type パラメータを使用します。
public <T> T findMax(T[] array) {
if (array == null || array.length == 0) {
return null;
}
T max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i].compareTo(max) > 0) {
max = array[i];
}
}
return max;
}
この例では、findMax
メソッドは型パラメーターを使用してT
未知の型を表しており、メソッドの呼び出し時に特定の型パラメーターを渡すことができます。たとえば、次のメソッドを呼び出して、整数の配列内の最大値を見つけることができます。
Integer[] numbers = {
1, 5, 3, 9, 2};
Integer max = findMax(numbers); // 获取整数数组中的最大值
このメソッドは、文字列の配列内の最大値を見つけるために呼び出すこともできます。
String[] strings = {
"apple", "banana", "cherry", "date"};
String max = findMax(strings); // 获取字符串数组中的最大值
型パラメーターを使用すると、クラス、インターフェイス、メソッドは定義時に未知の型を表すことができるため、コードがより汎用的かつ柔軟になり、さまざまな種類のデータに対応できるようになります。これはフレームワークで広く使用されており、いくつかの実用的な例を次に示します。
実践例
1. Java コレクション フレームワークのジェネリック:
Java コレクション フレームワークの多くのインターフェイスとクラスは、ジェネリックを使用して、コレクション内の要素の型を表します (例: 、ArrayList
などLinkedList
) HashMap
。ジェネリックスを使用することにより、これらのコレクション クラスは実行時にさまざまな型の要素をサポートし、コンパイル時に型安全性チェックを提供できるため、実行時の型変換エラーの可能性を回避できます。
ArrayList<Integer> numbers = new ArrayList<Integer>(); // 创建一个整数列表
numbers.add(1);
numbers.add(2);
numbers.add(3);
int firstNumber = numbers.get(0); // 获取列表中的第一个整数
ArrayList<String> names = new ArrayList<String>(); // 创建一个字符串列表
names.add("Alice");
names.add("Bob");
names.add("Charlie");
String firstName = names.get(0); // 获取列表中的第一个字符串
2. Spring フレームワークのジェネリック:
Spring Framework は、柔軟で拡張可能な機能を実現するためにジェネリックが広範囲に使用される Java アプリケーションを構築するための強力なフレームワークです。たとえば、Spring では、依存関係の注入、データ アクセス、トランザクション管理などのシナリオでジェネリックを使用できます。
public interface CrudRepository<T, ID extends Serializable> {
T save(T entity); // 保存实体
T findById(ID id); // 根据ID查询实体
void delete(T entity); // 删除实体
// ...
}
この例では、CrudRepository
インターフェイスは 2 つの汎用パラメーターT
とを使用しID
、それぞれエンティティ タイプと ID タイプを表します。ジェネリックスを使用すると、CrudRepository
インターフェイスの実装時に特定のエンティティ タイプと ID タイプを指定できるため、さまざまなエンティティ タイプと ID タイプのサポートが実現します。
public class UserRepositoryImpl implements CrudRepository<User, Long> {
// 实现User实体的数据访问操作
// ...
}
この例では、UserRepositoryImpl
クラスはCrudRepository
インターフェイスを実装し、エンティティの種類をUser
、ID の種類を として指定するLong
ことで、User
エンティティに対するデータ アクセス操作を実現します。
ジェネリックスを使用すると、汎用的で柔軟かつ拡張可能な機能をフレームワークに実装できるため、コードの再利用性と保守性が向上します。
3. カスタム フレームワークのジェネリック:
カスタム フレームワークまたはライブラリでは、ジェネリックを使用して一般的で柔軟な機能を実現することもできます。たとえば、ジェネリックを通じてさまざまなエンティティ タイプのデータ アクセス操作をサポートできる一般的なデータ アクセス層フレームワークを構築しているとします。
public interface CrudRepository<T, ID> {
T save(T entity); // 保存实体
T findById(ID id); // 根据ID查询实体
void delete(T entity); // 删除实体
// ...
}
この例では、ジェネリックCrudRepository
インターフェイスを定義します。ジェネリック パラメータはT
エンティティ タイプとID
ID タイプを表します。ジェネリックスを使用すると、CrudRepository
インターフェイスの実装時に特定のエンティティ タイプと ID タイプを指定できるため、さまざまなエンティティや ID タイプに対するデータ アクセス操作が実現します。
public class UserRepositoryImpl implements CrudRepository<User, Long> {
// 实现User实体的数据访问操作
// ...
}
この例では、UserRepositoryImpl
クラスはCrudRepository
インターフェイスを実装し、エンティティの種類をUser
、ID の種類を として指定するLong
ことで、User
エンティティに対するデータ アクセス操作を実現します。
カスタム フレームワークでジェネリックスを使用することにより、共通の機能を実現でき、ユーザーはフレームワークを使用する際にさまざまな種類のパラメーターを柔軟に指定できるため、さまざまなビジネス ニーズに対応できます。このような設計により、型変換エラーや実行時例外の可能性を回避しながら、フレームワークの再利用性と柔軟性を向上させることができます。
4. メソッド内のジェネリック:
メソッドでジェネリックスを使用すると、メソッドがより一般化され、複数のタイプの入力パラメータと戻り値を処理できるようになります。たとえば、Java のコレクション フレームワークの多くのメソッドはジェネリックを使用します。
public class CollectionUtils {
public static <T> T getFirstElement(List<T> list) {
if (list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
}
getFirstElement
この例では、型のジェネリック パラメーターを受け取りList<T>
、 の型を返す静的メソッドを定義しますT
。List
これは、このメソッドがなどの任意の型を処理できることを意味しますList<Integer>
。List<String>
ジェネリックスを使用するメソッドは、呼び出し時に実際のパラメーターの型に基づいて型推論を実行できるため、型変換エラーを回避し、より優れた型安全性とコードの再利用を実現できます。
Spring フレームワークでは、共通の機能を実現するためにジェネリックも広く使用されています。たとえば、Spring の JdbcTemplate クラスでは、ジェネリックはさまざまな種類のデータベース操作をサポートするために使用され、それによってコードの繰り返しが減り、柔軟性が向上します。
public class JdbcTemplate {
public <T> T queryForObject(String sql, RowMapper<T> rowMapper) {
// 执行SQL查询,并将结果映射到实体对象
// ...
}
// ...
}
この例では、queryForObject
メソッドは汎用パラメーターを使用してT
クエリ結果マッピングのエンティティ タイプを示し、RowMapper<T>
結果マッピングのパラメーターを受け取ります。このように、さまざまなRowMapper
エンティティ タイプに対するクエリ操作は、さまざまな実装クラスを渡すことで実現できるため、柔軟性と汎用性が向上します。
要約:
Java では、ジェネリックは、クラス、インターフェイス、メソッドなどで使用して、一般的で柔軟なタイプセーフな関数を実現できる強力な機能です。また、フレームワークでも広く使用されており、共通の機能を提供し、コードの重複を減らし、柔軟性と型安全性を向上させ、それによってコードの品質と開発効率を向上させることができます。