1.概念:是一种未知的数据类型,在不确定该用什么数据类型时,可以使用泛型。其中 E 代表未知的数据类型。
例子
1.public class ArrayList<E>{};
2.public class get<E>{};//创建对象时,会确定泛型的数据类型。
2.使用泛型的好处
创建集合对象使用泛型
好处:1.避免了类型转换的麻烦,储存的是什么类型,取出的就是什么类型
2 .把运行期异常提升到编译期异常。
坏处:泛型是什么类型,就能存储什么类型。
创建集合对象不使用泛型
好处:集合对象不使用泛型,那么默认就是Object类型,可以储存任意类型数据。
弊端:不安全,引发异常。
3.定义和使用泛型的类
代码实现
public class deom01 {
public static void main(String[] args){
//不写泛型,默认Object类型
GenericClass g1=new GenericClass();
g1.setName("张三");
Object obj1 = g1.getName();
System.out.println(obj1);
//创建对象使用Integer类型
GenericClass <Integer> g2=new GenericClass();
g2.setName(1);
Integer int1=g2.getName();
System.out.println(int1);
}
}
public class GenericClass<E> {
private E name;
public void setName(E name){
this.name=name;
}
public E getName(){
return this.name;
}
}
4.定义和使用泛型的方法
格式:
修饰符<泛型>返回值类型 方法名(参数列表(使用泛型)){方法体}
含有泛型的方法,在调用时确定数据类型。
代码实现:
public class GenericClass<E> {
//定义泛型的方法
public <M> void method01(M m){
System.out.println(m);
}
//定义一个含有泛型的静态方法
public static <E> void method02(E e){
System.out.println(e);
}
}
public class deom01 {
public static void main(String[] args){
GenericClass g1=new GenericClass();
g1.method01(1);
g1.method01("sb");
g1.method01('A');
//调用静态方法
GenericClass .method02("张三");
}
}
5.含有泛型的接口
第一种使用方式:定义接口的实现类,实现接口,实现类指定接口的泛型。
public interface GenericClass<E> {
void method(E e);
}
class GenerticClass1 implements GenericClass<String>{
public void method(String e){
System.out.println(e);
}
}
第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,相当于定义一个含有泛型的类,创建对象的时候确定泛型的类型。
public interface GenericClass<E> {
void method(E e);
}
class GenerticClass1<E> implements GenericClass<E>{
public void method(E e){
System.out.println(e);
}
}
public class deom01 {
public static void main(String[] args){
GenerticClass1<Integer> G=new GenerticClass1<>();
G.method(1);
GenerticClass1<String> G1=new GenerticClass1<>();
G1.method("张三");
}
}
6.泛型的通配符
通配符:<?>, 不知道用什么类型数据接收的时候,可以用通配符。
只能接受数据,不能往集合存储数据。注意:泛型是没继承的概念。
代码实现
import java.util.ArrayList;
import java.util.Iterator;
public class deom01 {
public static void main(String[] args){
ArrayList<Integer> list01=new ArrayList();
list01.add(1);
list01.add(2);
ArrayList<String> list02=new ArrayList();
list02.add("w");
list02.add("s");
printArray(list01);
printArray(list02);
}
public static void printArray(ArrayList<?> arr){
Iterator<?> it=arr.iterator();//不能创建对象使用,只能作为参数的使用
while(it.hasNext()){
Object obj=it.next();
System.out.println(obj);
}
}
}
7.通配符的高级使用——受限泛型
泛型的上限
.格式:类型名称<? extend类>对象名称
.意义:只能接受该类型及其子类。
泛型的下限
.格式:类型名称<? super类>对象名称
.意义:只能接受该类型及其父类。
补充:Integer extends Number extends Object | | |String extends Object
代码实现:
public class Demo1{
public static void main(String[] args){
Collection<Interger> list1=new Arraylist<>();
Collection<String> list2=new Arraylist<>();
Collection<Number> list3=new Arraylist<>();
Collection<Object> list4=new Arraylist<>();
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
public static void getElement1(Collection<? extends Number> coll){}//上限
public static void getElement2<Collection<? super Number>coll{}//下限
}