6 java泛型总结
2017-01-14 16:50
337 查看
1 简介
泛型即“参数化类型”。
自定义泛型接口、泛型类和泛型方法。
泛型类型在逻辑上看似看成是多个不同的类型,实际上都是相同的基本类型。
2 基本用法
1)泛型类
泛型之前使用Object类,但是Object类强制转化为其他类时容易出错。
泛型使得代码更简便安全。
2)泛型方法
3 类型擦除
1)什么是类型擦除
类型参数只存在于编译期,在运行时,Java的虚拟机(JVM)并不知道泛型的存在。
2) 擦除带来的问题
解决办法:
加上一个边界
3)类型擦除的补偿
任何在运行期需要知道确认类型的代码都无法工作。
4 泛型数组
1)如何创建泛型数组
2)使用 T[] array
3 使用反射
5 数组的协变
6 使用通配符
1)上边界限定通配符
2)下边界限定通配符
泛型即“参数化类型”。
自定义泛型接口、泛型类和泛型方法。
泛型类型在逻辑上看似看成是多个不同的类型,实际上都是相同的基本类型。
2 基本用法
1)泛型类
泛型之前使用Object类,但是Object类强制转化为其他类时容易出错。
package javazongjie; public class Holder<T> { private T t; public Holder(T t) { super(); this.t = t; } public T getT() { return t; } public void setT(T t) { this.t = t; } public static void main(String[] args) { Holder<String> holder = new Holder<>("Hello T!"); System.out.println(holder.getT()); } }
泛型使得代码更简便安全。
2)泛型方法
package javazongjie; public class GenericMethod { public <K,V> void f(K k,V v) { System.out.println(k.getClass().getSimpleName()); System.out.println(v.getClass().getSimpleName()); } public static void main(String[] args) { GenericMethod genericMethod = new GenericMethod(); genericMethod.f(new Integer(1), new String("abc")); //>>Integer //>>String } }
3 类型擦除
1)什么是类型擦除
类型参数只存在于编译期,在运行时,Java的虚拟机(JVM)并不知道泛型的存在。
package javazongjie; import java.util.ArrayList; public class ErasedTypeEquivalence { public static void main(String[] args) { Class c1 = new ArrayList<String>().getClass(); Class c2 = new ArrayList<Integer>().getClass(); System.out.println(c1 == c2); //>>true //在JVM看来它们是同一个类 } }
2) 擦除带来的问题
package javazongjie; public class HasF { public void f() { System.out.println("HasF.f()"); } }
package javazongjie; public class Manipulator<T> { private T obj; public Manipulator(T obj) { super(); this.obj = obj; } public void manipulate() { obj.f(); //编译出错 } }
解决办法:
加上一个边界
package javazongjie; public class Manipulator<T extends HasF> { private T obj; public Manipulator(T obj) { super(); this.obj = obj; } public void manipulate() { obj.f(); } }
3)类型擦除的补偿
任何在运行期需要知道确认类型的代码都无法工作。
4 泛型数组
1)如何创建泛型数组
package javazongjie; public class ArrayOfGeneric { static final int SIZE = 100; static Holder<Integer>[] holder; public static void main(String[] args) { //holder = new Holder<Integer>[SIZE];//编译错误 holder = (Holder<Integer>[])new Holder[SIZE]; System.out.println(holder.getClass().getName()); //输出[Ljavazongjie.Holder; //成功创建泛型数组的唯一方式是创建一个类型擦除的数组,然后转型 holder[0] = new Holder<Integer>(1); } }
2)使用 T[] array
package javazongjie; public class GenericArray<T extends Integer> { private T[] array; @SuppressWarnings("unchecked") public GenericArray(int sz) { array = (T[])new Integer[sz]; } public void put(int index, T item) { array[index] = item; } public T get(int index) { return array[index]; } public T[] rep() { return array; } public static void main(String[] args) { GenericArray<Integer> gai = new GenericArray<Integer>(10); gai.put(0, 100); System.out.println(gai.get(0)); } }
3 使用反射
package javazongjie; import java.lang.reflect.Array; public class GenericArrayWithTypeToken<T> { private T[] array; public GenericArrayWithTypeToken(Class<T> type, int sz) { array = (T[])Array.newInstance(type, sz); } public void put(int index, T item) { array[index] = item; } public T get(int index) { return array[index]; } public T[] rep() { return array; } public static void main(String[] args) { GenericArrayWithTypeToken<Integer> gai = new GenericArrayWithTypeToken<Integer>( Integer.class, 10); Integer[] ia = gai.rep(); System.out.println(ia); } }
5 数组的协变
class Fruit {} class Apple extends Fruit {} class Jonathan extends Apple {} class Orange extends Fruit {} public class CovariantArrays { public static void main(String[] args) { Fruit[] fruit = new Apple[10]; fruit[0] = new Apple(); // OK fruit[1] = new Jonathan(); // OK // Runtime type is Apple[], not Fruit[] or Orange[]: try { // Compiler allows you to add Fruit: fruit[0] = new Fruit(); // ArrayStoreException } catch(Exception e) { System.out.println(e); } try { // Compiler allows you to add Oranges: fruit[0] = new Orange(); // ArrayStoreException } catch(Exception e) { System.out.println(e); } } } /* Output: java.lang.ArrayStoreException: Fruit java.lang.ArrayStoreException: Orange *///:~
6 使用通配符
1)上边界限定通配符
<? extends Fruit>
2)下边界限定通配符
? super T