English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
このチュートリアルでは、Javaの汎用型、汎用クラスとメソッドの作成方法、その利点について例を通じて学びます。
Javaでは、泛型異なるタイプのオブジェクト(データ)と一緒に使用できるクラス、インターフェース、メソッドを作成するのに役立ちます。したがって、コードの再利用を可能にします。
注意:泛型汎用型は基本データ型(int、float、charなど)には適用できません。
Javaでどう使うかを理解するために泛型、ArrayListJava集合フレームワークのクラスを使用できます。
ArrayListクラスは汎用クラスの1つの例です。どんなデータ型のデータもArrayListで格納できます。例えば
import java.util.ArrayList; class Main { public static void main(String[] args) { //Integerデータを格納するための配列リストを作成します ArrayList<Integer> list1 = new ArrayList<>(); list1.add(4); list1.add(5); System.out.println("ArrayList of Integer: ") + list1); //Stringデータを格納するための配列リストを作成します ArrayList<String> list2 = new ArrayList<>(); list2.add("Four"); list2.add("Five"); System.out.println("ArrayList of String: ") + list2); //Doubleデータを格納するための配列リストを作成します ArrayList<Double> list3 = new ArrayList<>(); list3.add(4.5); list3.add(6.5); System.out.println("ArrayList of Double: " + list3); } }
输出结果
ArrayList of Integer: [4, 5] ArrayList of String: [Four, Five] ArrayList of Double: [4.5, 6.5]
上の例では、Integer、String、Doubleのデータ型の要素を格納するために同じArrayListクラスを使用しました。なぜなら、Javaの汎用、これは可能です。
ここに注意してください、
ArrayList<Integer> list1 = new ArrayList<>();
ここで、尖括号<>にはIntegerを使用しました。尖括号<>は汎用における型引数.
パラメータtypeは、汎用クラスやメソッドがどのオブジェクト(データ)の種類に適用されるかを指定します。
Javaで汎用の動作方法を知った今、自分自身の汎用クラスを作成する方法を見てみましょう。
class Main { public static void main(String[] args) { //整数データで汎用クラスを初期化します GenericsClass<Integer> intObj = new GenericsClass<>(5); System.out.println("汎用クラスは返します: " + intObj.getData()); //文字データで汎用クラスを初期化します GenericsClass<String> stringObj = new GenericsClass<>("Java Programming"); System.out.println("汎用クラスは返します: " + stringObj.getData()); } } class GenericsClass<T> { //T型変数 private T data; public GenericsClass(T data) { this.data = data; } //T型変数を返すメソッド public T getData() { return this.data; } }
输出结果
汎用クラスは返します: 5 汎用クラスは返します: Java プログラミング
上の例では、GenericsClassという名前の汎用クラスを作成しました。このクラスはどんなデータの種類でも処理できます。
class GenericsClass<T> {...
ここでは、Tを表します型引数Mainクラス内部で、intObjとstringObjという名前のGenericsClassオブジェクトを作成しました。
在创建intObj时,类型参数T被Integer替换。这意味着intObj使用GenericsClass处理整数数据。
在创建stringObj时,类型参数T被String替换。 这意味着stringObj使用GenericsClass处理字符串数据。
与泛型类相似,我们还可以在Java中创建自己的泛型方法。
class Main { public static void main(String[] args) { //使用Integer数据初始化类 DemoClass demo = new DemoClass(); demo.<String>genericsMethod("Java Programming"); } } class DemoClass { //泛型方法 public <T> void genericsMethod(T data) { System.out.println("这是一个泛型方法。"); System.out.println("传递给方法的数据是 " + data); } }
输出结果
这是一个泛型方法。 传递给方法的数据是: Java Programming
在上面的示例中,我们创建了一个在普通类(DemoClass)内部命名的泛型方法genericsMethod。
public <T> void genericMethod(T data) {...}
在此,将类型参数<T>插入到修饰符(public)之后和返回类型(void)之前。
我们可以通过将实际类型<String>放在方法名前面的括号中来调用泛型方法。
demo.<String>genericMethod("Java Programming");
注意:在大多数情况下,我们可以在调用泛型方法时省略type参数。这是因为编译器可以使用传递给方法的值来匹配类型参数。例如,
demo.genericsMethod("Java Programming");
通常,typeパラメータ可以接受任何数据类型(原始类型除外)。但是,如果我们只想将泛型用于某些特定类型(例如接受数字类型的数据),则可以使用有界类型。
我们使用extends关键字。例如,
<T extends A>
这意味着T只能接受A的子类型的数据。
class GenericsClass<T extends Number> { public void display() {}} System.out.println("This is a bounded type generics class."); } } class Main { public static void main(String[] args) { //GenericsClassオブジェクトを作成します GenericsClass<String> obj = new GenericsClass<>(); } }
上記の例では、以下を作成しました有界型の泛型クラス。ここでは、以下の式に注意してください
<T extends Number>
これはTがNumberのサブタイプデータタイプ(Integer、Doubleなど)のみを使用できることを意味します。
しかし、私たちはStringで泛型クラスのオブジェクトを作成していました。そのため、プログラムを実行すると、以下のようなエラーが発生します。
GenericsClass<String> obj = new GenericsClass<>(); ^ reason: inference variable T has incompatible bounds equality constraints: String lower bounds: Number where Tは型-変数: class GenericsClassで宣言されたT extends Number
泛型異なるデータタイプに適用できるコードを書くことができます。例えば、
public <T> void genericsMethod(T data) {...}
ここでは、泛型メソッドを作成しました。このメソッドは整数データ、文字列データなどに対して操作を実行するために使用できます。
泛型のtypeパラメータ泛型コードで使用されるデータタイプに関する情報を提供します。
そのため、コンパイル時にエラーを検出することができ、ランタイムエラーよりも簡単に修正できます。例えば、
//泛型を使用していません NormalClass list = new NormalClass(); //NormalClassのメソッドを呼び出します list.display("String");
上記のコードでは、普通のクラスがあります。このクラスのdisplay()メソッドに文字列データを渡して呼び出します。
ここでは、コンパイラはパラメータに渡された値が正しいかどうかを知りません。しかし、泛型クラスを使用してみるとどうなるかを見てみましょう。
//ジェネリクスの使用 GenericsClass<Integer> list = new GenericsClass<>(); //GenericsClassのメソッドを呼び出します list2.display("String"); 上記のコードでは、ジェネリクスクラスがあります。ここでは、タイプパラメータはこのクラスがIntegerデータを処理していることを示しています。 したがって、文字列データが引数として渡された場合、コンパイラはエラーを生成します。
コレクションフレームワークはJavaのジェネリクス概念を使用しています。例えば、
// 文字列型のArrayListを作成します ArrayList<String> list1 = new ArrayList<>(); // 整数型のArrayListを作成します ArrayList<Integer> list2 = new ArrayList<>();
上記の例では、異なるデータタイプを処理するために同じArrayListクラスを使用しました。
ArrayListと同様に、他のコレクション(LinkedList、Queue、Mapsなど)もJavaのジェネリクスです。