https://bbs.csdn.net/topics/390949113

如:创建一个List
List list = new ArrayList();
List list = new ArrayList();
创建一个Map
Map map = new HashMap();
Map<String,String> map = HashMap<String,String>();
指定类型与不指定类型,这两种方式在底层有什么区别,或者在性能上有什么影响呢?

指定了参数类型编译器在编译期间就会帮助你检查存入容器的对象是不是参数类型!不是就会报错!保证了类型安全!性能上没什么影响,因为泛型在运行期间会擦除!就是说用不用类型参数在运行期间编译后的运行代码是一样的! Map map = new HashMap(); Map<String,String> map1 =new HashMap<String,String>(); System.out.println(map.getClass().equals(map1.getClass()));返回结果会true;说明他们运行的是同一份字节码!


一个好的使用泛型的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Gen<Integer> intOb = new Gen<Integer>(88);
intOb.showType();
int i = intOb.getOb();
System.out.println("value= " + i);
System.out.println("----------------------------------");
// 定义泛型类Gen的一个String版本
Gen<String> strOb = new Gen<String>("Hello Gen!");
strOb.showType();
String s = strOb.getOb();
System.out.println("value= " + s);


//-------------------------------------------------------------------------
// 定义类Gen2的一个Integer版本

Gen2 intOb_ = new Gen2(new Integer(88));
intOb_.showTyep();
int i_ = (Integer) intOb_.getOb();
System.out.println("value= " + i_);
System.out.println("---------------------------------");
// 定义类Gen2的一个String版本
Gen2 strOb_ = new Gen2("Hello Gen!");
strOb_.showTyep();
String s_ = (String) strOb_.getOb();
System.out.println("value= " + s_);

泛型带?的用法 上界通配符 https://www.liaoxuefeng.com/wiki/1252599548343744/1265105899616928

使用类似<? extends Number>通配符作为方法参数时表示:

方法内部可以调用获取Number引用的方法,例如:Number n = obj.getFirst();;

方法内部无法调用传入Number引用的方法(null除外),例如:obj.setFirst(Number n);。

即一句话总结:使用extends通配符表示可以读,不能写。

使用类似定义泛型类时表示:

泛型类型限定为Number以及Number的子类。


所以我的尴尬症就犯了。实际上,编译器脑袋里认定的逻辑是这样的:

苹果 IS-A 水果
装苹果的盘子 NOT-IS-A 装水果的盘子
所以,就算容器里装的东西之间有继承关系,但容器之间是没有继承关系的。
原因很明显,因为Plate不是Plate的子类,因此,printFruit(Plate)不接受参数类型Plate

为了让泛型用起来更舒服,Sun的大脑袋们就想出了<? extends T>和<? super T>的办法,来让“水果盘子”和“苹果盘子”之间发生关系。

Plate<? extends Fruit>

翻译成人话就是:一个能放水果以及一切是水果派生类的盘子。再直白点就是:啥水果都能放的盘子。

supper类似 下面图里表示用了<?extends/super>后能装的范围