java 泛型介绍

显示类型说明

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.java

abstract 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.java

interface 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.java
import 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> succeeded
ClassAsFactory<Integer> failed
*///:~

泛型的类型擦除引起的泛型数组问题

package generics;//: generics/GenericArrayWithTypeToken.java
import 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.java
import 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值