java Class的泛型笔记

首先拿java的List做一个例子:

 

public interface List <E> {
    void add(E x);
    Iterator<E> iterator();
}

public interface Iterator<E> {
    E next();
    boolean hasNext();
}
在上面的例子里,E被称为参数化类型:parameterized type,它可以被诸如Integer(类型参数,actual type argument)代替
public interface IntegerList {
    void add(Integer x);
    Iterator<Integer> iterator();
}
 
 
另外的一个例子:

public static  void printCollection(List<Object> c) {         for (Object e : c) {             System.out.println(e);         }     }

    public static void main(String[] args) {         List<Integer>a=new ArrayList<Integer>();         a.add(2);         a.add(1);         printCollection(a);     }

这是一个编译期便会出现问题的例子:上面的list只能接收Object,而它不是所有类型的list的父类
于是在java的泛型中引入了? List<?> 意义为:list of unknown ,用它来做所有类型的List的父类。List<?>匹配所有类型的list,它被称为通配符,英文为 wildcard type。
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
上面的collection便用到了通配符,但是当往collection里添加一个object时还是报错,官方给出的解释是:因为我们不知道c的类型到底是什么,所以我们不能往里添加任何的东西,因为我们add的任何参数都必须是?的子类。但是有一个例外:null.
 
有限制的通配符: bounded wildcard
比如 Circle extends Shape{}
Rectangle extends Shape{}
List<? extends Shape>即为一个有限制的通配符的例子,其中shape是? 的上限,upper bound
 
泛型方法:
static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    for (T o : a) {
        c.add(o); // Correct
    }
}
 
现在的问题是,什么时候用通配符? 什么时候用泛型方法T?
 
官方文档的解释是这样的:
Wildcards are designed to support flexible subtyping
 
Generic methods allow type parameters to be used to express dependencies among the types of one or more arguments to a method and/or its return type. If there isn't such a dependency, a generic method should not be used.
 
也就是说,T这个泛型方法,需要用在有继承关系的地方,在Collections.copy中的方法:
class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src) {
    ...
}
 
当然,官方推荐使用?:Using wildcards is clearer and more concise than declaring explicit type parameters, and should therefore be preferred whenever possible.
 
比如下面的这个例子:
class Collections {
    public static <T, S extends T> void copy(List<T> dest, List<S> src) {
    ...
}
S只是用了一次,所以用?代替也无妨
 
最后,? 的使用十分的灵活,它不单单只能使用在方法签名,还能用在数组,变量之中
static List<List<? extends Shape>> 
    history = new ArrayList<List<? extends Shape>>();
 
泛型类被所有的调用方共享,无论类型参数是什么,在运行时的泛型类都有统一的类,于是就有了下面的结果:
List <String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
返回TRUE哦
在JDK5之后,java.lang.Class也变成了泛型。。。。。
比如Class<T> 这个T表示的意思就是这个class object代表的类型,举个例子,String.class就是Class<String>
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值