一个小栗子聊聊JAVA泛型基础
2017-09-23 19:44
330 查看
背景
周五本该是愉快的,可是今天花了一个早上查问题,为什么要花一个早上?我把原因总结为两点:日志信息严重丢失,茫茫代码毫无头绪。
对泛型的认识不够,导致代码出现了BUG。
第一个原因可以通过以后编码谨慎的打日志来解决,我们今天主要来一起回顾下JAVA泛型基础。
一个小栗子
先看下面一个例子,test1实例化一个List容器的时候没有指定泛型参数,那么我们可以往这个容器里面放入任何类型的对象,这样是不是很爽?但是当我们从容器中取出容器中的对象的时候我们必须小心翼翼,因为容器中的对象具有运行时的类型信息,这意味着你不能够将一个带有运行时类型信息的对象赋值给另一个类型,否则ClassCastException。@Test public void test1() throws Exception { List list = new ArrayList(); list.add("float.lu"); list.add(1); String name = (String) list.get(0); int num = (Integer) list.get(1); System.out.println(String.format("name[%s], num[%s]", name, num)); } |
引入泛型
为了解决这个问题,我们引入泛型,下面代码可以看出与上面不同的是我们在实例化容器的时候加了<String>这个东西,这个东西的学名叫做泛型参数,就像普通方法带有参数一样,interface List<E>中的E为形式参数、而String为实参。@Test public void test2() throws Exception { List<String> list = new ArrayList<String>(); list.add("a"); list.add(1)//1 } |
别高兴太早
有了泛型我们可以让代码安全地通过编译,并且我们认为他是安全的了,嘿嘿,是否就真的安全了呢?是否就能和ClassCastException说拜拜了呢?答案是:NO。看看下面这段代码:@Test public void test3() throws Exception { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); List _list = list; List<Integer> integerList = _list; for (Integer item : integerList) { System.out.println(String.format("item[%s]", item)); } } |
泛型术语
在学习数学的时候我们往往会对一个证明题进行论证,而论证之前我们手上往往会有一些不需要证明的已知定理,下面这些“定理”将被用来直接回答上一节中遗留的问题。List<E>被称作泛型类型。
List<E>中的E被称为类型变量或类型参数。
List<String>被称为参数化类型。
List<String>中的String被称为实际类型参数。
List<E>中的<>年typeof。
List被称为原始类型。
参数化类型可以引用一个原始类型对象,编译报告警告。
原始类型可以引用一个参数化类型对象,编译报告警告。
由上可知,List<Integer> integerList = _list;可以通过编译。
看清本质
经过上面的一些小波折,我们了解一些关于泛型的本质:泛型是给javac编译器使用的,javac是JAVA的编译器,而泛型可以让代码在编译期间确定类型安全,比如我们告诉编译器某个容器只能存储某种类型的对象,那么编译器会为我们好好地检查,确保类型安全,但是安全是相对的,只要我们逃过编译器,我们就有一百种方法让代码ClassCastException(比如反射)。同时编译之后参数化类型在运行时没有任何泛型信息,也就是为什么List.class和List<String>.class是同一个东西。除了参数化类型之外,容器中的对象在运行的时候是有类型信息的,也就是为什么会ClassCastExcetion。关于泛型还有很多内容,这里不做多讲,文中有误也欢迎留言讨论。相关文章推荐
- 一个小栗子聊聊JAVA泛型基础
- 【Java基础】一个有意思的泛型方法Arrays.asList(T... a)
- 一天一个Java基础——泛型
- 一个比较综合的Java语言基础试题
- 『JAVA基础』朋友的需求,关于一个算法
- “泛型Java”,一个美丽的hype
- Java基础:Java泛型编程快速入门
- Java基础-如何编写一个JAVA的队列类-Java基础-Java-编程开发
- 如何轻松编写一个强大的字符串分解器-Java基础-Java-编程开发
- Java基础-设计一个Java类所需的方法-Java基础-Java-编程开发
- JAVA基础:Java泛型编程快速入门
- [转]Java基础:一个关于java数组的深度思考
- 呵呵:一个好玩的题目 Java的基础知识
- 用Java Swing作一个日历控制程序-Java基础-Java-编程开发
- Java基础视频笔记(四):泛型
- 一个比较综合的Java语言基础试题
- Java基础:Java泛型编程快速入门
- Java网络编程基础 1 建立一个提供当前时间字符串的ServerSocket
- 用AJAX J2EE实现一个网上会议室系统-Java基础-Java-编程开发
- Java基础:Java泛型编程快速入门