一直不是很明白泛型中的?和K、V的区别,查了一些资料,自己做了一些理解:
1.K、V决定了这个结构只能使用一种类型,而?则表示该结构可以接受满足条件的所有类型的对象
2.在一个类实例化的时候可以定义该类固定的一个泛型,如用A、B表示,则需要用到这个泛型的方法和成员变量可以直接使用它,指的就是那个在实例化该类时定义的类型。
3.对于方法,想要使用泛型则?和K、V等字母表示都是可以的,如set方法,使用V表示泛型,则需要在方法申明时特别定义,写在返回值之前,如果使用?来表示泛型则在要使用的地方进行定义,如set2方法。
4.在定义成员变量时如果要使用泛型,必须使用?,如果要使用字母表示,这个字母必须是类在实例化的时候定义的,即之前讲的不能在定义成员变量的时候临时定义一个字母作泛型。
建议:直观理解就是字母作泛型应该是在类实例化的时候定义出来,如果没有这样的设置,还是用?统一的好。
public class Generics<A,B> {
private Map<String, Test<? extends Math>> map = new HashMap<String, Test<? extends Math>>();
private Map<Integer, ? extends String> map2 = new HashMap<Integer, String>();
private List<A> list = new ArrayList<A>();
private List<B> list3 = new ArrayList<B>();
// private List<T> list2 = new ArrayList<T>();//错误,不能在申明成员变量的时候去定义泛型T的类型,必须在类实例化的时候
public <T extends Exception> T get() {
return null;
}
public A get2() {
return null;
}
public <V extends String> void set(List<V> list) {
System.out.println(list.get(0).getClass().getName());
}
public void set2(List<? extends String> list) {
System.out.println(list.get(0).getClass().getName());
}
// private <A extends String> List<A> list = new ArrayList<A>();
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("aaa");
Generics<Integer,String> demo = new Generics<Integer,String>();
demo.set(list);
demo.set2(list);
}
}
class Test<T> {
}