概述
泛型在Java中有着很重要的地位,在面向对象编程及各种设计模式中都有非常广泛的应用。
概念
广泛的类型。
为什么要使用泛型?
1、将错误从运行时期提前到了编译时期。
(在jdk1.5之前,集合中可以装各种各样的对象,这样取出来对象只能用Object对象接受,但是当要明确其类型时,必须强制转换,而且强制转换的错误只能在
运行期才能发现。然而jdk1.5新特性泛型彻底解决了这样的问题。
泛型规定一个类只能装什么,取出时也无需强制转换,因为限定了装什么,也就知道取出是什么了。
若装其它东西会在编译时期就报错,这样就将以前的运行时错误提前到编译时期了。)
2、不再需要进行强制类型转换。
3、简化开发,保证质量。
本质:在泛型使用过程中,操作的数据类型可以指定为一个参数,这个参数类型可以被应用到类,接口,方法中。
常见的T,E,K,V等形式的参数常作为参数类型用来表示泛型。
在实例化泛型类型时,必须指定参数类型的具体类型。
概念:广泛的类型。
作用
限制类型
//泛型指定类型之后要求改集合中只能存放指定类型的数据
List<String> list = new ArrayList<String>();
不限制类型
很多查询功能,返回的都是List集合,操作流程和方式一样,但是集合中存储的类型不同例如:List、List、List
使用
在类中使用
class 类名称<参数类型>
class OneTest<speak>{
//在类上定义的泛型,在该类中可以当成是一个新的数据类型
private speak one;
/* public OneTest() {
}*/
//在类上定义的泛型,构造方法形参one,two的类型也称为speak
public OneTest(int i) {
// TODO Auto-generated constructor stub
}
public OneTest(speak one) {
super();
this.one = one;
}
public OneTest(double d) {
// TODO Auto-generated constructor stub
}
public OneTest(boolean b) {
// TODO Auto-generated constructor stub
}
public OneTest(String string) {
// TODO Auto-generated constructor stub
}
public speak getOne() {
return one;
}
}
class TwoTest<speak>{
/*
* 定义的泛型类,就一定要传入泛型类型的实参吗?并不是这样,在使用泛型的时候 如果传入泛型实参,此时才会起到泛型本身的限制作用
* 如果不传入泛型类型参数的话,在泛型类中使用的泛型的方法或着成员变量定义的类型可以成为任何的类型
*/
OneTest<speak> one =new OneTest<speak>("abc");
OneTest<speak> two =new OneTest<speak>(101);
OneTest<speak> twree =new OneTest<speak>(8.15);
OneTest<speak> four =new OneTest<speak>(false);
}
在方法中使用
在方法上使用,该类型只能该方法中生效,放在修饰符的后面返回值类型的前面
public <T> List<T> query(T t){
return null;
}
通配符
当具体类型不确定时,就可以使用?;当操作类型是,不需要使用类型的具体功能时,只使用Object类中的功能,那么就可以用?通配符来表示未知功能。
public List<?> queryList(){
List<?> list = new ArrayList<>();
return list;
}
注意:不能创建一个确切的泛型数组
List<speak>[] a = new ArrayList<speak>[10];//错误
List<?>[] a = new ArrayList<?>[10];//可以编译
List<String>[] a = new ArrayList[10];//可以编译
数组的类型不可以是类型变量,除非是采用通配符的方式,因为对于通配符的方式最后去除的数据时要做显示转换的。