Java 泛型
来源:互联网 发布:erp软件系统 报表 编辑:程序博客网 时间:2024/05/22 11:23
泛型即为类、方法、变量等提供“类型参数”,都是使用<>包括起来。意思是告诉系统我需要定义一些类型参数了,接下来我会使用这些类型参数。基础知识不再详细列出,仅列出一些值得注意和较难理解的问题。
为什么要使用泛型?
Java中,使用泛型最主要的原因是增加类型的安全性,以及简化代码避免显式的强制类型转换。 从性能上说Java泛型并没有加快,这里涉及到运行时擦除概念和编译器默认加入的类型转换。 所以说Java中的主要作用就是增加安全和简化代码。不同的类型参数用逗号分隔
<T,S extends List>
,S表示其是List的子类型。 如果泛型S要同时进行继承和接口的限制,那么需要把继承类写在第一位,如<S extends ClassName & interfaceName1 & interfaceName2>
。另外在类上面的泛型编码一般不会使用限制符,影响扩展。因为运行时擦除的原因,下面两个方法并不是普通的方法重载,而就是同一个方法,编译器是会报错的。
public void go(List<String i){}public void go(List<Integer i){}
也因为运行时擦除,所以使用instanceof这种实例级别的语法去校验是不对的,因为擦除了泛型还如何去校验呢。同理,比较两个泛型对象的getClass显然应该得到相等的结果。
- 容易晕头的通配符使用。集合类型中的?和? extends方式,是可以赋值的,但是不能add任何非null对象。原因是我们在直接赋值的时候保证了整个集合是同一个类型的。但是在add的时候我们无法知道add进去的类型是否和集合中已经存在的类型是同一类型(虽然都是shape的子类)。这样就会产生问题。
List<? extend Shape> l = new ArrayList<Circle>();//赋值时必须是Shape的子类l.add(new Object());//error!!只要不是null,全都是错误的
集合中? super方式,也是可以赋值的,但是赋值时必须的Shape的超类。同时这种形式允许add,add的是Shape的子类,因为这样肯定可以的知道这个元素至少可上溯造型至shape,如果是Shape的超类就不行了,原因和extends类似。
List<? extend Circle> l = new ArrayList<Shape>();//只要是Circle的超类都可以赋值,赋值时保证了集合中的元素是同一种类型。l.add(new Circle());l.add(new SubCircle());//只要是Circle的子类,就一定能上溯造型成Circle甚至是在赋值语句中Circle的超类。l.add(new Circle某超类());//error!!类似extends,因为并不知道集合内有没有其它的超类
何时使用extends何时使用super,可以遵循PECS原则,即如果你是泛型对象的提供者、生产者,那你身上应该使用extends。 如果你是泛型对象的消费者,那你身上应该使用super。
泛型数组是不合法的,记住不要这么用(除非通配符)。
借用泛型可以让一个集合里拥有很多不同类型的对象各一个,其实是借助了泛型化的Class作为key。
Map<Class<?>,Object>。
- 【java 2】java泛型
- Java 泛型 Java generic
- Java Tutorials_Generics(java泛型)
- Java基础 Java 泛型
- java 泛型
- java泛型
- Java泛型
- Java泛型
- java泛型
- java泛型
- java泛型
- Java 泛型
- Java泛型
- Java 泛型
- JAVA 泛型
- java 泛型
- java泛型
- Java泛型
- java.lang.IllegalThreadStateException: Thread already started.
- project euler 81
- 使用导入导出域移动虚拟机时注意事项
- 整理:深度学习 vs 机器学习 vs 模式识别
- 栈和堆的区别是什么? 为什么说栈的速度快,堆的速度慢?
- Java 泛型
- 微信服务器在填写服务器的配置返回token验证失败
- js数组引用传值问题
- 代理(Proxy)模式一
- Android 百分比布局库(percent-support-lib) 解析与扩展
- php开发环境搭建
- 工作五年以上的程序员,应该干些什么
- 面向对象
- session