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

原创粉丝点击