java 泛型介绍
来源:互联网 发布:安卓手机数据迁移软件 编辑:程序博客网 时间:2024/05/21 05:57
显示类型说明
Java 泛型 类型参数推断和显示类型说明
public class New { /** * 这就是类型推断 */ public static <K, V> Map<K, V> map() { return new HashMap<K, V>(); } public static <T> List<T> list() { return new ArrayList<T>(); } public static <T> LinkedList<T> lList() { return new LinkedList<T>(); } public static <T> Set<T> set() { return new HashSet<T>(); } public static <T> Queue<T> queue() { return new LinkedList<T>(); } public static void main(String[] args) { Map<Person, List<? extends Person>> pet = New.map(); f(pet); // f(New.map()) 类型推断只对赋值操作有效。其他时候并不起作用 f(New.<Person, List<? extends Person>>map());// 显示的类型说明-- 静态方法在点(.)操作符前用类名,非静态this } static void f(Map<Person, List<? extends Person>> pet) { System.out.println(pet); }}
注:
泛型方法使得该方法能够独立于类而产生变化,一下的一个基本的指导原则:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛型化,那么久应该只使用泛型方法,因为它可以使事情更清楚明白。
擦除的补偿
泛型参数在创建对象的时候,不能直接使用new 关键字的方式创建
第一种模板方法
package generics;//: generics/CreatorGeneric.javaabstract class GenericWithCreate<T> { final T element; GenericWithCreate() { element = create(); } abstract T create();}class X {}class Creator extends GenericWithCreate<X> { X create() { return new X(); } void f() { System.out.println(element.getClass().getSimpleName()); }} public class CreatorGeneric { public static void main(String[] args) { Creator c = new Creator(); c.f(); }} /* Output:X*///:~
第二种工厂方法
package generics;//: generics/FactoryConstraint.javainterface FactoryI<T> { T create();}class Foo2<T> { private T x; public <F extends FactoryI<T>> Foo2(F factory) { x = factory.create(); } // ...}class IntegerFactory implements FactoryI<Integer> { public Integer create() { return new Integer(0); }} class Widget { public static class Factory implements FactoryI<Widget> { public Widget create() { return new Widget(); } }}public class FactoryConstraint { public static void main(String[] args) { new Foo2<Integer>(new IntegerFactory()); new Foo2<Widget>(new Widget.Factory()); }} ///:~
第三种方法 Class.newInstance();方法
Class.newInstance()的方法,只有类存在默认的构造方法的时候,才能使用,不然会出现异常:
java.lang.RuntimeException: java.lang.InstantiationException: java.lang.Integer
package generics;//: generics/InstantiateGenericType.javaimport static net.mindview.util.Print.*;class ClassAsFactory<T> { T x; public ClassAsFactory(Class<T> kind) { try { x = kind.newInstance(); } catch(Exception e) { throw new RuntimeException(e); } }}class Employee {} public class InstantiateGenericType { public static void main(String[] args) { ClassAsFactory<Employee> fe = new ClassAsFactory<Employee>(Employee.class); print("ClassAsFactory<Employee> succeeded"); try { ClassAsFactory<Integer> fi = new ClassAsFactory<Integer>(Integer.class); } catch(Exception e) { print("ClassAsFactory<Integer> failed"); } }} /* Output:ClassAsFactory<Employee> succeededClassAsFactory<Integer> failed*///:~
泛型的类型擦除引起的泛型数组问题
package generics;//: generics/GenericArrayWithTypeToken.javaimport java.lang.reflect.*;public class GenericArrayWithTypeToken<T> { private T[] array; @SuppressWarnings("unchecked") public GenericArrayWithTypeToken(Class<T> type, int sz) { array = (T[])Array.newInstance(type, sz); //T[] array=new T[10];//这样的代码是不能编译的 //Object[] array = new Object[sz]; //这样数组添加和单个获取都问题,但是获取整个数组就会出现转型错误java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer; } public void put(int index, T item) { array[index] = item; } public T get(int index) { return array[index]; } // Expose the underlying representation: public T[] rep() { return array; } public static void main(String[] args) { GenericArrayWithTypeToken<Integer> gai = new GenericArrayWithTypeToken<Integer>( Integer.class, 10); // This now works: Integer[] ia = gai.rep(); }} ///:~
泛型容器的问题
package generics;//: generics/GenericReading.javaimport java.util.*;public class GenericReading<T> { static <T> T readExact(List<T> list) { return list.get(0); } static <T> void add(List<T> list,T t) { list.add(t); }// static List<Apple> apples = Arrays.asList(new Apple());//创建的为不能修改固定大小的List容器L,故不能执行新增// static List<Fruit> fruit = Arrays.asList(new Fruit()); static List<Apple> apples = new ArrayList<Apple>(); static List<Fruit> fruit = new ArrayList<Fruit>(); static{ apples.add(new Apple()); fruit.add(new Fruit()); } static void f1() { Fruit a = readExact(apples); Fruit f = readExact(fruit); add(fruit, new Apple()); f = readExact(apples); } static class CovariantReader<T> { //如果在类的泛型限定类中。 继承方式边界的泛型限定容器,可以传入类的泛型限定类的子类容器, //如果不是类的泛型限定类中,则需要继承限定边界也能达到 T readCovariant(List<? extends T> list) { return list.get(0); } //如果在类的泛型限定类中:逆变(超类型通配符),可以传入类的泛型限定类的子类容器, 如果不是类的泛型限定类中,则需要继承限定边界也能达到 void add(List<? super T> list, T t){ list.add(t); }} static void f3() { CovariantReader<Fruit> fruitReader = new CovariantReader<Fruit>(); Fruit f = fruitReader.readCovariant(fruit); Fruit a = fruitReader.readCovariant(apples); fruitReader.add(fruit,new Apple()); System.out.println(""); } public static void main(String[] args) { f2();f3(); }} ///:~
引用文章:http://blog.csdn.net/s10461/article/details/53941091
阅读全文
0 0
- Java泛型介绍
- java泛型介绍
- java泛型介绍
- java 泛型介绍
- java 泛型介绍
- Java泛型介绍
- Java中的泛型介绍
- java泛型基本介绍
- java泛型详细介绍
- java -- 泛型简单介绍
- Java中的泛型使用详细介绍
- Java中的泛型使用详细介绍
- java泛型介绍及使用
- Java泛型的介绍与使用
- java自定义泛型和反射泛型介绍
- 黑马程序员---转载关于java泛型的详细介绍
- Java泛型介绍——HashMap总结
- java泛型的简单介绍及使用
- 170604 逆向-CrackMe之013
- SVG 绘制可交互的中国地图
- windows下解压版MYSQL的配置
- EF5 DBContext与Entity分离
- C++: A a() 和 A a 的区别。
- java 泛型介绍
- linux给数字加千位符(正则)
- 189.m1-Fragment工厂优化Fragment的加载
- 文件的读取中几个函数的使用
- 文件读取中函数的使用
- 正则删除HTML标签
- java nio 基础之Select 用法
- Null Byte Injection
- 博文测试