讲解泛型之前,先看看如下的例子
List list = new ArrayList();
list.add(999);
list.add("abc");
list.add(new Date());
那么对于的数据是怎么加载进去的呢,jdk源码是这样的
list.add都是默认增加Object类型数据,但是在数据获取中就必须要知道每个数据的类型,而且很容易产生ClassCastException异常,那么在jdk1.5引入泛型的概念.
指定list中存储的参数类型,如: List<String> list = new ArrayList<String>();这样就指定list只能装载String类型的数据。
但是在编译的时候出现一个奇怪的现象:
java代码
List<String> list = new ArrayList<String>();
list.add("999");
list.add("abc");
编译后的代码
<String>参数消失了
1. 泛型原理:类型擦出(type erasure)
类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。在使用泛型时,任何具体的类型都被擦除,唯一知道的是你在使用一个对象。比如:List<String>和List<Integer>在运行事实上是相同的类型。他们都被擦除成他们的原生类型,即List
在此有一个问题,既然泛型类型中清除了相关参数,那么系统又是如何在数据返回的时候自动转换呢?
通过两个步骤来解决
1.编译期会自动对传递进来的值进行检测,例如:List<String> list 对于增加list.add(9999)的时候编译会报错。
2.获取数据会把 获取的值按照传递的参数类型转换,list.get(0)的时候,系统会自动对这些值进行String的转换。
父类和子类在泛型中注意事项
List<String> childrenList = new ArrayList<String>();
List<Object> parentList = new ArrayList<Object>();
一下两种形式都不能转换
hildrenList = parentList;
parentList = childrenList;
在泛型一个List中装入了各种不同类型的对象类型,这显然是不可以的,
因为我们在取出List中的对象类型时,就分不清楚到底该转型为哪种具体类型了(获取数据泛型会自动对传递的类型按参数设定的转换)
泛型定义注意
public static <T> List<T> get(String tu){
return null;
}
public <T> List<T> getBO (String tu){
return null;
}
2. 通配符:这里使用了通配符?指定可以使用任何类型的集合作为参数
注意:试图往使用通配符?的集合中加入对象,就会在编译时出现错误。 这是因为通配符?表示该集合存储的元素类型未知,可以是任何类型;因为该集合存储的元素类型未知,所以不能向集合中添加任何元素。
List<?> list = someMothod(arg);
list.add(object);//编译的时候会报错。
但是 从List<?> list中获取对象,虽然不知道List中存储的是什么类型,但是可以肯定的是存储的类型一定是Object的子类型,所以可以用Object类型来获取值。如for(Object obj: list)循坏获取对象,这个事允许的。
2.1 ?extends通配符
类型 children extends parent 通配符必须是父类的子类。也称作限定通配符。
List<? extends Number> list;
那么?类型只能是Number的子类,例如 Integer,Long,Float等,但是这里不能list.add(String)。
在获取数据的时候
取出其中对象时,可以使用Number类型来取值,因为虽然我们不知道列表中的元素类型具体是什么类型,
但是一定是Number类的子类型。
for(Number m:list){
.....
}
2.2 ?super通配符
类型 A super B 通配符A必须是B类的超类
List<? super B> list;
这表示list存储的元素为B的超类,因此可以往其中加入B对象或者B的子类对象,但是不能加入其他对象,只要是B或者B的子类,则一定是与该元素类别兼容。
具体使用规则: 一个数据类型里获取数据,使用 ? extends 通配符
把对象写入一个数据结构里,使用 ? super 通配符
3.泛型方法:泛型方法的格式,类型参数<T>需要放在函数返回值之前。然后在参数和返回值中就可以使用泛型参数
public static <T> List<T> get(String tu){
return null;
}
public <T> List<T> getBO (String tu){
return null;
}
public <T> void getM1(T obj){
}
另外实际中经常出现的汇总一下;
1》. 泛型类型是被所有调用共享的
1》. 泛型类型是被所有调用共享的
所有泛型类的实例都共享同一个运行时类,类型参数信息会在编译时被擦除。
List<String> list1 = new ArrayList<String>();
List<Integer> list2 = new ArrayList<Integer>();
System.out.println(list1.getClass() == list2.getClass()); //True
2》 数组是协变的,如:Object[] objArray = new Long[10]是合法的,因为Long是Object的子类,与之相反,泛型是不可协变的,如List<Object> objList = new List<Long>()是非法的,将无法通过编译
相关推荐
关于java基础的泛型的练习
【Java基础】泛型方法 - 右撇子 - 博客频道 - CSDN.NET
java基础-泛型通配符
下面是那种典型用法: List myIntList = new ArrayList();// 1 myIntList.add(new Integer(0));// 2 Integer x = (Integer) myIntList.iterator().next();// 3 第3 行的类型转换有些烦人。通常情况下,程序员知道一...
大学课程讲义_Java基础_泛型.docx
集合框架及泛型的介绍和基础理解,方便大家了解集合框架及泛型。
java零基础自学 之 JAVA泛型 java零基础自学 之 JAVA泛型
自己整理的JAVA学习笔记,非计算机专业,包括数据基础和泛型编程,集合,多线程,IO流,网络部分未上传,如果觉得对你有帮助就很棒啦!
详细的介绍了集合框架的用法,及其语法规则,剖析了使用的使用注意事项,帮助更牢靠的掌握集合框架的知识及泛型内容。谢谢
Java基础入门(四)-泛型、反射、注解
思维导图
Java 课件 (包括基础语法,数组与语句,面向对象编程,java异常处理,java常用基础类,java集合与泛型)
java基础泛型 学习全文件
该文档主要包括为什么使用泛型、在集合中使用泛型、自定义泛型结构、泛型在集成上的体现以及通配符的使用等内容
Java泛型概念 Java泛型是一种在编译时进行类型检查和类型推断的机制,它可以让我们编写更加通用、可重用的代码,提高了代码的可读性和可维护性,同时保证了类型安全。 Java泛型的核心思想是类型参数化,即在类、接口...
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...
学士后Java集合框架和泛型课后习题答案 希望能够帮助大家更好的学习JAVA,这些知识还是比较基础的,并没有多大难度 一起共同进步
这是我在网络上学习所收获到的一些心得,想和大家分享一下。如有侵权或者错误请大家私信我,我会进行删除与修改。
Java SE编程入门教程 java泛型(共11页).pptx Java SE编程入门教程 java封装继承多态(共56页).pptx Java SE编程入门教程 java集合(共38页).pptx Java SE编程入门教程 java接口(共21页).pptx Java SE编程入门...
有一定Java编程基础的开发者;对泛型概念感兴趣或希望加深理解的学习者。 使用场景: 学习和理解Java泛型的基本概念和语法; 实际项目中需要使用泛型来增加类型安全性和重用性的开发任务。 目标: 本代码资源的...