Java Generics (ジェネリック) は、JDK5 で導入された新機能で、クラスとインターフェイスを定義するときに型パラメーター (Type Parameter) を使用できるようにします。宣言された型パラメーターは、使用時に特定の型に置き換えられます。現在、ジェネリックスの最も重要なアプリケーションは、Map と List が使用される JDK5 の新しいコレクション クラス フレームワークにあります。利点は自明ですが、ジェネリック クラスを使用する場合は、コードの目的を明確にする必要があり、型を使用できないため、欠点は実際には利点になります。
最も基本的なジェネリッククラス
package com.garinzhang.javabase.generic.e1; /** * 最基本的泛型类,类型由自己定义 * @author Garin Zhang * * @param <T> */ public class Point<T> { private T var; public T getVar() { return var; } public void setVar(T var) { this.var = var; } } package com.garinzhang.javabase.generic.e1; public class GenericExample { /** * @param args */ public static void main(String[] args) { Point<String> p = new Point<String> (); p.setVar("coder"); System.out.println(p.getVar()); } }
複数のジェネリック型
package com.garinzhang.javabase.generic.e2; /** * 多个泛型类型,一般多个最好是以靠近T的字母,如S,R等 * @author Garin Zhang * * @param <T> * @param <S> */ public class Notepad<T, S> { private T key; private S value; public T getKey() { return this.key; } public S getValue() { return this.value; } public void setKey(T key) { this.key = key; } public void setValue(S value) { this.value = value; } } package com.garinzhang.javabase.generic.e2; public class GenericExample { /** * @param args */ public static void main(String[] args) { Notepad<String, Integer> p = new Notepad<String, Integer> (); p.setKey("coder"); p.setValue(99999); System.out.println("key: " + p.getKey()); System.out.println("value: " + p.getValue()); } }
メソッドパラメータでのワイルドカード「?」の使用
package com.garinzhang.javabase.generic.e3; /** * 该例子关键在main方法里 * @author Garin Zhang * * @param <T> */ public class Info<T> { private T key; public T getKey() { return this.key; } public void setKey(T key) { this.key = key; } @Override public String toString() { return this.key.toString(); } } package com.garinzhang.javabase.generic.e3; /** * 在方法参数中使用通配符 * @author Garin Zhang * */ public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<String> i = new Info<String>(); i.setKey("coder"); fun(i); Info<Integer> j = new Info<Integer>(); j.setKey(9999); fun(j); } public static void fun(Info<?> temp) { System.out.println("Content: " + temp); } }
アップキャストの失敗
package com.garinzhang.javabase.generic.e4; /** * 该例子关键在main方法里 * @author Garin Zhang * * @param <T> */ public class Info<T> { private T key; public T getKey() { return this.key; } public void setKey(T key) { this.key = key; } @Override public String toString() { return this.key.toString(); } } package com.garinzhang.javabase.generic.e4; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<String> strEg = new Info<String>(); Info<Object> objEg; // 编译错误"Type mismatch: cannot convert from Info<String> to Info<Object>" // 向上转型失败,String -> Object // objEg = strEg; } }
インターフェースでのジェネリックの使用
package com.garinzhang.javabase.generic.e5; /** * 该例子关键在main方法里 * @author Garin Zhang * * @param <T> */ interface Info<T> { public T getVar(); } package com.garinzhang.javabase.generic.e5; /** * 泛型类 * @author Garin Zhang * * @param <T> */ public class InfoImpl<T> implements Info<T> { private T var; public InfoImpl(T var) { this.setVar(var); } public void setVar(T var) { this.var = var; } public T getVar() { return this.var; } } package com.garinzhang.javabase.generic.e5; /** * 非泛型类 * @author Garin Zhang * * @param <T> */ public class InfoImpl1 implements Info<String> { private String var; public InfoImpl1(String var) { this.setVar(var); } public void setVar(String var) { this.var = var; } public String getVar() { return this.var; } } package com.garinzhang.javabase.generic.e5; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<String> strEg = new InfoImpl<String>("coder"); System.out.println("Content: " + strEg.getVar()); Info<String> strEg1 = new InfoImpl1("coder1"); System.out.println("Content: " + strEg1.getVar()); } }
ワイルドカードとextends、super
package com.garinzhang.javabase.generic.e6; /** * 该例子关键在main方法里 * @author Garin Zhang * * @param <T> */ public class Info<T> { private T key; public T getKey() { return this.key; } public void setKey(T key) { this.key = key; } @Override public String toString() { return this.key.toString(); } } package com.garinzhang.javabase.generic.e6; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<String> strEg = new Info<String>(); strEg.setKey("coder"); // 编译报错"The method fun(Info<? extends Number>) in the type GenericExample is not applicable for the arguments (Info<String>)" // upTypeLimit(i); // 使用Integer,Number类型均可以 Info<Integer> intEg = new Info<Integer>(); intEg.setKey(9999); upTypeLimit(intEg); // 编译报错"The method downTypeLimit(Info<? super String>) in the type GenericExample is not applicable for the arguments (Info<Integer>)" // downTypeLimit(intEg); // 由于使用的是super,downTypeLimit只能接收String本身和Object // 查看了String的继承关系,没有继承其他类,只有Object downTypeLimit(strEg); Info<Object> objEg = new Info<Object>(); objEg.setKey(999); downTypeLimit(objEg); } /** * <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 * @param temp */ public static void upTypeLimit(Info<? extends Number> temp) { System.out.println("Content: " + temp); } /** * <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object * 在此例中,表示T只能为Object或String,因为String只继承于Object * @param temp */ public static void downTypeLimit(Info<? super String> temp) { System.out.println("Content: " + temp); } }の使用
メソッドのジェネリックス、メソッド内の複数のジェネリックス
package com.garinzhang.javabase.generic.e7; /** * 方法泛型,方法里面多个泛型 * @author Garin Zhang * * @param <T> */ public class Info { /** * 格式:方法修饰付 <以逗号隔开的类型列表>返回值类型方法名(参数列表) * 例如:public <T, S> T fun(T t, S s) * @param t * @param s * @return */ public <T, S> T fun(T t, S s) { System.out.println(s.toString()); return t; } } package com.garinzhang.javabase.generic.e7; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info info = new Info(); String str = info.fun("coder", "print second generic param"); System.out.println(str); int i = info.fun(30, "print second param again"); System.out.println(i); } }
メソッドで渡される、または返されるジェネリック型は、メソッド呼び出し時に設定されたパラメータの型によって決まります
package com.garinzhang.javabase.generic.e8; /** * extends * @author Garin Zhang * * @param <T> */ public class Info<T extends Number> { private T var; public T getVar() { return this.var; } public void setVar(T var) { this.var = var; } @Override public String toString() { return this.var.toString(); } } package com.garinzhang.javabase.generic.e8; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<Integer> intEg = fun(30); // 这里类型已经确定为Integer System.out.println(intEg.getVar()); } /** * 方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定 * @param param * @return */ public static <T extends Number> Info<T> fun(T param) { Info<T> temp = new Info<T>(); temp.setVar(param); return temp; } }
メソッドに2つ渡されるようにします
package com.garinzhang.javabase.generic.e9; /** * 查看main * @author Garin Zhang * * @param <T> */ public class Info<T> { private T var; public T getVar() { return this.var; } public void setVar(T var) { this.var = var; } @Override public String toString() { return this.var.toString(); } } package com.garinzhang.javabase.generic.e9; public class GenericExample { /** * @param args */ public static void main(String[] args) { Info<String> i1 = new Info<String>(); i1.setVar("Hello"); Info<String> i2 = new Info<String>(); i2.setVar("Coder"); Info<Integer> i3 = new Info<Integer>(); i3.setVar(999); add(i1, i2); //编译错误"The method add(Info<T>, Info<T>) in the type GenericExample is not applicable for the arguments (Info<String>, Info<Integer>)" // add(i1, i3); } /** * 方法中传入两个参数类型必须一致 * @param param * @return */ public static <T> void add(Info<T> i1, Info<T> i2) { System.out.println(i1.getVar() + ":" + i2.getVar()); } }
パラメータの型は一貫したままです
package com.garinzhang.javabase.generic.e10; public class GenericExample { /** * @param args */ public static void main(String[] args) { Integer i[] = fun(1, 2, 3, 4, 5, 6); fun2(i); } public static <T> T[] fun(T... arg) { return arg; } public static <T> void fun2(T param[]) { System.out.println("generic array: "); for(T t : param) { System.out.println(t + " ,"); } } }
ジェネリック、変数パラメータ、JavaScript の Arguments オブジェクトに似ています
package com.garinzhang.javabase.generic.e11; /** * 接受两个泛型类型 * @author Garin Zhang * * @param <T> */ public class Info<T, V> { private T var; private V value; public T getVar() { return this.var; } public void setVar(T var) { this.var = var; } public V getValue(){ return this.value; } public void setValue(V value) { this.value = value; } @Override public String toString() { return this.var.toString(); } } package com.garinzhang.javabase.generic.e11; /** * 接受1个泛型类型 * @author Garin Zhang * * @param <T> */ public class Demo<S> { private S info; public Demo(S info) { this.setInfo(info); } public void setInfo(S info) { this.info = info; } public S getInfo() { return this.info; } } package com.garinzhang.javabase.generic.e11; import java.util.List; import com.google.common.collect.Lists; public class GenericExample { /** * @param args */ public static void main(String[] args) { Demo<Info<String, Integer>> d; Info<String, Integer> i; i = new Info<String, Integer>(); i.setVar("Coder"); i.setValue(999); d = new Demo<Info<String,Integer>>(i); System.out.println("Content: " + d.getInfo().getVar()); System.out.println("Content: " + d.getInfo().getValue()); System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5] // 警告"Type safety: A generic array of Object&Comparable<?>&Serializable is created for a varargs parameter" System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType] System.out.println(query("I ", "am ", "a ", "coder").toString());// [I , am , a , coder] List<String> list = Lists.newArrayList("I ", "am ", "a ", "coder"); System.out.println(list.toString()); // [I , am , a , coder] } /** * 通过返回值确定泛型类型,这个方法里面的返回值类型,是由方法的定义自动生成的 * @param elements * @return */ public static <E> List<E> query(E... elements) { // https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16. // import com.google.common.collect.Lists; // <dependency> // <groupId>com.google.guava</groupId> // <artifactId>guava</artifactId> // <version>16.0.1</version> // </dependency> return Lists.newArrayList(elements); } }
ジェネリックの入れ子: ジェネリック クラスをパラメータとして使用し、戻り値の型に基づいて戻り値を決定します
rrreee🎜Java の一般的な学習例に関連する記事については、お支払いください。 PHP 中国語 Web サイトに注意してください。 🎜