通过这些网友分享的资料
https://www.cnblogs.com/lwbqqyumidi/p/3837629.html
https://www.cnblogs.com/lihaoyang/p/7104293.html
为什么出现java泛型:
先看一个例子: List list = new List(); list.add(Object); 可以添加任何是 object子类的对象
假如添加了 String 后又添加 int 在输出的时候通过for循环:
String name = (String) list.get(i);
System.out.println("name:" + name);
那么会出现 java.lang.ClassCastException 异常。这是在强转的数据类型的时候导致的。
这种胡乱添加的行为如果没有按规定当然是会出差错。 java泛型的提出就是一个规范,规范了一组数据的类型一致性。即便有人想乱来也不会添加数据成功。
我自己对泛型实现的思路:
(1)需要一个方法阻止别人乱来。(2)这个方法如何实现?(3) java的方法 public void fun();
(4)要阻止别人乱来就需要一个限制。(5) public void fun(int XXX);(6) 可以利用参数的类型作为入口的限制,限制了入口,别人想乱来也不可能(7)正是这个参数类型,使得别人想传个 string 或者其他类型进来都会编译失败。(8)那么基于这个思想,可以扩大到为 类,对象 实现这种规范。
这个实现被java 叫 : 参数化类型 即 泛型
List<String> list = new ArrayList<String>();
list.add("qqyumidi"); list.add("corn"); 这样想乱叫别的类型自然是报错的
自定义泛型:
class abc <T>{
private T i;
public T Gettaobao() { return i; }
public void ste(T i) { this.i = i; } }
在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,由于接收来自外部使用时候传入的类型实参。
注意:
abc <Integer> age = new abc<>(); abc <String> agS = new abc<>(); System.out.println("name class:" + age.getClass()); // name class:class exercise.abc System.out.println("age class:" + agS.getClass()); // age class:class exercise.abc System.out.println(agS.getClass() == age.getClass()); // true
我们发现,在使用泛型类时,虽然传入了不同的泛型实参,但并没有真正意义上生成不同的类型,传入不同泛型实参的泛型类在内存上只有一个,即还是原来的最基本的类型(本实例中为Box),当然,在逻辑上我们可以理解成多个不同的泛型类型。
为什么?为什么?为什么?
其原因,在于Java中的泛型这一概念提出的目的,导致其只是作用于代码编译阶段,在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦出,也就是说,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段。所以想看泛型实现的源码的同学还是不要和我一样痴心妄想了。
类型通配符 ? 的此处不讲。
进一步拓展: 继承泛型类
extends 子类继承了 泛型父类
class abcd<T> extends abc<T> //那么子类必须也是泛型
通过java继承可知,父类的一切包括 泛型 也会被继承过来。
但是在实现泛型的时候又是有些区别:
class abc <T,E> //father
class abcd<T, E> extends abc<T,E> //全保留
class abcd<T> extends abc<T,Integer> //部分参数类型保留下而已,但是父类的泛型有一个参数必须具体化。否则会报错
class abcd<A,B> extends abc<String,Integer>
class abcd<A,B> extends abc//类型擦除
拓展小知识:
class ab<A,B> extends Father//泛型擦除时,(按object处理)(存在警告)。
ab<object,object> a = new ab<object, object > ()
ab a = new ab ()
上述两个创建对象在编译时,虽然同样是按 object 处理,但是 第一个会进行 类型检查,不会出现警告。第二个会出现警告,不会类型检查
拓展大知识: 泛型接口:与泛型类 同理。
Java中的实际类型信息不管是编译时期还是在运行时期都被擦除了,这就是擦除的效果。由于有了擦除,Java编译器无法将obj调用f()这一需求映射到HasF拥有f()这一事实上。(事实上擦除是将泛型类型信息擦除到了它的第一个边界,默认不设置的边界是Object,你可以调用Object的方法,可以这样设置边界——<T extends HasF>,设置边界后就可以调用f()了
---------------------
作者:李简单
来源:CSDN
原文:https://blog.csdn.net/holleykitty/article/details/80481527
版权声明:本文为博主原创文章,转载请附上博文链接!
网友评论