泛型
泛型的概述:
把类型明确的工作推迟到创建对象或调用方法之后,简单来说,你有一个类,在使用时内部类型暂不确定,给使用给一个占位符给代替,在使用的时候可以给确定其定义的类型。
泛型的优点
- 代码更加简洁【不用强制转换】
- 程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常】
- 可读性和稳定性【在编写集合的时候,就限定了类型】
泛型的约束和局限性
-
不能用基本类型实例化类型参数----不能用类型参数代替基本类型
-
运行时类型查询只适用于原始类型(区分:和类型擦除中的限定类型不一样)
-
不能创建参数化类型的数组
-
不能实例化类型变量
-
泛型类的静态上下文中类型变量无效–泛型类中的静态域或静态方法不能引用泛型变量
-
可以消除对受查异常的检查
使用泛型和不使用泛型的区别
-
不使用泛型
集合不使用泛型,默认类型是Object类型,可以存储任意类型。但是会引发类型转换异常。
-
使用泛型
避免了类型转换的麻烦,存储什么类型,取出什么类型,把运行期异常提醒到编译器。但是集合也就只能存储泛型指定的类型。
泛型的定义和使用
泛型类
定义格式:修饰符 class 类名<泛型>{}
public class Test {
public static void main(String[] args) {
//在创建类的新的对象时,要指明泛型的类型,不然默认为Object类型。
ArrayTest<Integer> arrayTest = new ArrayTest<>();
}
}
//<E>在使用泛型时,可以将类型参数写为任意的标识(要求:大写字母就行)。
class ArrayTest<E>{
}
泛型方法
定义格式:修饰符 <泛型> 返回值类型 方法名(参数(使用泛型)){}
public class Test {
public static void main(String[] args) {
fx("qqqq");
}
//在方法中给了<S>泛型,此时默认<S>为Object类型,也可以修改为其他类型。
public static <S> void fx(S e){
System.out.println(e);
}
}
泛型接口
第一种方法:定义接口的实现类,实现接口,指定接口的泛型
第二种方法:定义接口的实现类,接口是什么类型,指定实现类也是相同的接口,类跟着接口走,相当于确定了一个泛型类
//第一种方法:定义接口的实现类,实现接口,指定接口的泛型
public class Test {
public static void main(String[] args) {
Face<String> face= new test();
}
}
//定义一个接口,给出泛型为<E>;
interface Face<E>{
}
//定义一个类Blog实现接口Face,
class Blog implements Face{
}
//第二种方法:定义接口的实现类,接口是什么类型,指定实现类也是相同的接口,类跟着接口走,相当于确定了一个泛型类
public class Test {
public static void main(String[] args) {
Test1<String> s = new Test1<>();
}
}
//指定接口泛型为<E>
interface Face<E>{
}
//指定类实现接口,并且类的泛型跟接口一样
class Test1<E> implements Face {
}
泛型的通配符
泛型的通配符:?,代表任意数据类型
使用方式:不能通过创建对象使用;只能作为方法的参数使用
public class Test {
public static void main(String[] args) {
//? 表示任意的数据类型
Collection<?> list = new ArrayList<Object>();
Collection<?> list1 = new ArrayList<Student>();
}
}
泛型的限定
泛型上限限定:? extend E,表示使用的泛型只能是E类的子类或者本身
泛型下限限定:? super E,表示使用的泛型只能是E类的父类或者本身
public class Test {
public static void main(String[] args) {
//?extend Test1Fu泛型上限限定,只能作用给Test1Fu的子类Test1或者他本身。
ArrayList<? extends Test1FU> test1 = new ArrayList<Test1>();
ArrayList<? extends Test1FU> test2 = new ArrayList<Test1FU>();
//?super Test1Fu泛型下限限定,只能作用给自身或者自身的父类。
ArrayList<? super Test1FU> test1 = new ArrayList<Object>();
ArrayList<? super Test1FU> test2 = new ArrayList<Test1FU>();
}
}
class Test1FU{
}
interface Face<E>{
}
class Test1<E>extends Test1FU implements Face {
}