Java泛型学习笔记
来源:互联网 发布:关口知宏妻子 编辑:程序博客网 时间:2024/05/13 21:35
这是一篇零散的学习笔记,涉及到一些Java泛型遇到的知识点,不是系统学习
语法糖
泛型算是一种语法糖,本质上和直接存Object是一样的,只不过通过泛型,编译器会对这个类做一个类型转换,能将问题发现在编译期。
区分:泛型类和类型参数
class A<T>{ T t;}
在上面的实例中,A是泛型类,而T是泛型参数。
擦除
前面说到,泛型是一种语法糖,所以在虚拟机中,是没有泛型这个概念的,所以在编译时,编译器会把这些泛型参数转为其限定类型(如果没有限定上界,那就是Object),就叫做擦除。
因为擦除,运行时的类型信息就没有了,所以如果不做强制类型转换(显式地或者隐式的),那些需要在运行时知道确切信息的操作都无法进行(方法调用、创建类)。擦除很关键,几乎泛型所有的限制都与擦除这个机制有关。
通配符
前面说了通配符的概念,大概就是<? extends BoundingType>
或者<? super BoundingType>
这个BoudingType就叫做上界或者下界?
就叫做通配符。表示某个类的子类或者某个类的父类。这样的限定类型是可以用在定义和申明时的。下面一段代码说明了类的定义、申明和创建三个阶段。
public class A<? extends B>{ public static void main(String[] args){ List<? extends B> lists = new ArrayList<>(); }}
这里的class A...
就是类的定义部分,而List<? extends B> lists
是对List这个类进行申明,而new ArrayList<>()
是对类的创建部分。基本上,通配符在定义时的作用是限制子类或者在定义是确定参数类型(并给其确定一个限定上界/下界),通配符在申明时的作用是限定在创建确定类型参数(注意这个参数的限定上界仍然是在定义时确定的)。
菱形语法:Java7特性
如果在创建某个类时,申明类时确定了类型参数,那么创建中就不必再申明具体的类型参数,如之前的代码中,
List<? extends B> lists = new ArrayList<>();
这里ArrayList<>()
中是<>
而不是<B>
之类的,是因为在申明时就从语法上(没错加粗是因为我还是要强调其实本质上在运行时还是Object或者是限定类型),能确定这个类型参数了。注意这个要在Java7及以上用。
泛型类的数组初始化不合法
根本原因是,数组在创建的时候必须知道内部元素的类型,而且一直都会记得这个类型信息。而泛型类在创建时是不能确定类型的,考虑下面的例子:
List<String>[];List<Integer>[];
看起来截然不同的两个类,其实在创建时都是List[](List<Object>[])
,所以因为参数类型不能确定,所以数组不支持初始化。但是可以通过强制类型转换的方式的生成数组,例如如下的代码
//错误 // List<String>[] list1 = new List<String>[2]; //正确 List<String>[] list2 = (List<String>[]) new List[2];
参数化类型不能做需要运行时信息的事情
这个之前有所提到,即擦除的限制。比如下面的操作是非法的
public class A<T>{ public static void main(String[] args){ //直接通过new初始化不行 //T t = new T(); //调用不行,除非做了强制类型转换 //t.say(); }}
参数化类型作为静态上下文
静态上下文指的是,静态成员变量、静态代码块、静态方法。下面一段代码也是非法的。因为多个类都会共用这些静态的上下文,不同的实例申明创建时对待T可能是不同类型,这意味这就需要在编译时插入不同的类型转换代码,从而导致错误。
public class A<T> { //非法 private static T t; //非法 static{ T t; } //非法 public static void f(){ T t; }}
泛型与异常
泛型类是不能继承Throwable及其子类的,具体原因看下面这个例子:
//这段代码是错误的try { doSomeStuff();} catch (SomeException<Integer> e) { // ignore that} catch (SomeException<String> e) {}
其实本质上还是类型擦除的原因,这里明显两个异常类是一样的(运行时都是Object),显示是不行的,所以泛型类是不能继承Throwable及其子类的,而且泛型类也不能被捕获或者抛出。
虽然泛型类不能被抛出,但是这不妨碍类型参数被抛出,只要我们在最初设置一个类型参数的上界即可。
- Java泛型学习笔记
- java泛型学习笔记
- java泛型学习笔记
- java泛型学习笔记
- java 泛型学习笔记
- java 泛型学习笔记
- Java泛型学习笔记
- Java泛型学习笔记
- java泛型学习笔记
- Java泛型学习笔记
- Java泛型学习笔记
- Java学习笔记泛型
- Java 泛型学习笔记
- Java泛型学习笔记
- Java 泛型学习笔记(一)
- Java 泛型学习笔记(二)
- java学习笔记之泛型
- Java 泛型学习笔记(一)
- SpringMVC中Could not obtain transaction-synchronized Session for current thread的解决方案
- 唐诗宋词与我
- leetcode标记数组
- 获取文件的MIMEType
- PHP从5.3.9开始增加一个变量 max_input_vars 用来限制提交的表单数量
- Java泛型学习笔记
- iOS 比较详细的自定义framework编译方法
- 设置鼠标忙碌状态
- 1000句最常用英语口语 (五)
- MySQL数据库基本操作(数据库操作一)
- Unity Sprite 灰色图效果
- 下载安装sparse,进行代码检查编译
- js断点调试入门指导
- MyEclipse远程debug jboss7