java通配符之“?”

时间: 作者:走吧走吧

简介泛型类和泛型方法

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Example<T>{
private String test;
private T t;
public T getT(){
return t;
}
public void setT(T t){
this.t = t;
}
public <E> E getE(E e){
return e;
}
}

泛型类

上面的类Example就是一个泛型类,它在类名的后面加上< T >,不指定T的类型,却可以在类里面把T当做一个已知的类型来使用。

  • 使用1-在声明的时候规定类型
    1
    Example<String> ex = new Example<String>();

这时会把Example类里面所有的T替换为String。
常使用的例子,List集合的使用。

  • 使用2-继承该泛型类
    1
    2
    public Ex1 extends Example<Char>(){
    }

这时,类Ex1的所有方法(继承的)中的T都是Char型。
这样做的好处
就像一个模板一样,类里面的方法,可以供多个对象来使用。
常使用的例子,java在与数据库交互的时候封装的Dao层父类。

泛型方法

上面的getE方法就是泛型方法。

  • 使用
    1
    Boolean b = ex.getE(true);

这时返回的类型就Boolen型。

通配符?

1
2
3
Object obj = null;
String str = "";
obj = str;

上面的代码,是正确的。子类的值可以给基类。

但是泛型类型的子类型之间是互不相关的。

1
2
3
List<Object> objList = new ArrayList<Object>();
List<String> strList = new ArrayList<String>();
objList = strList;

这段代码就会报错。因为strList并不是objList的一个子类。
但是如果是 List< ?> list = null;
list = objList;
list = strList;
这样写就可以。

?就是通配符。

1
2
public void test2(List<?> coll){
}

上面的方法,我们就可以构造不同的泛型子类型当做参数。
List< String>、List< Char> 等都可以。

  • List< ?>声明了List中包含的元素类型是未知的。通配符所代表的其实是一组类型,但具体的类型是未知的。List< ?>所声明的就是所有类型都是可以的。但是List< ?>并不等同于objList。objList实际上确定了List中包含的是Object
    及其子类,在使用的时候都可以通过Object来进行引用。
  • List< ?>则其中所包含的元素类型是不确定。其中可能包含的是String,也可能是 Integer。如果它包含了String的话,往里面添加Integer类型的元素就是错误的。正因为类型未知,就不能通过new ArrayList< ?>()的方法来创建一个新的ArrayList对象。因为编译器无法知道具体的类型是什么。但是对于 List< ?>中的元素确总是可以用Object来引用的,因为虽然类型未知,但肯定是Object及其子类。

向上造型一个泛型对象的引用

1
<? extends XX>

extends可以理解为小于等于,任意类型要是XX的子类或者是XX。

假设我们有很多箱子,每个箱子里都装有不同的水果,我们需要找到一种方法能够通用的处理任何一箱水果。更通俗的说法,A是B的子类型,我们需要找到一种方法能够将C< A>类型的实例赋给一个C< B>类型的声明。

1
2
List<Apple> apples = new ArrayList<Apple>();
List<? extends Fruit> fruits = apples;

Apple是Fruit的子类型,List< Apple> 是 List< ? extends Fruit> 的子类型。

向下造型一个泛型对象的引用

1
<? super XX>

super可以理解为大于等于,任意类型要是XX的父类或者是XX。

1
2
List<Fruit> fruits = new ArrayList<Fruit>();  
List<? super Apple> = fruits;

Apple是Fruit的子类型,List< Fruit> 是 List< ? super Apple> 的父类型。

Java中泛型之类型通配符(?)
java通配符