Java 泛型系列二:限定类型、泛型的约束与局限性
本文概述:
- 本文为 Java 泛型系列第二篇文章,文章以具体业务场景,介绍了 Java 泛型当中的限定类型变量、泛型的局限性以及泛型的约束性;诸如,泛型可存在于静态中吗,泛型方法可以被static 修饰吗,泛型在异常中是如何使用的等等;
泛型:限定类型变量
-
业务需求:限定泛型类型(拥有compareTo() 方法的类型才能被传入)
-
代码:返回两数最小值
//指定泛型T 上限为某一类型/接口 package generic; public class MinValue { //定义泛型方法 public <T extends Comparable>T minValue(T number1,T number2){ if(number1.compareTo(number2) > 0){ return number2; }else{ return number1; } } public static void main(String[] args) { MinValue ma = new MinValue(); System.out.println(ma.minValue(1,2)); } } -
代码细节:
-
编译错误出现:
- 如果实参没有继承限定类或者实现限定接口时,将报编译错误
-
限定类型细节:
-
可以是类或者接口,且允许同时出现,但需遵循单继承多实现规则
-
当类与接口混用时,需要将类写在首位
-
受限定的泛型与其限定类型可以有多个,例如泛型T,V 均需实现接口1,2
//不同接口以 & 进行分割 public static<T,V extends 接口1 & 接口2>
-
-
泛型:泛型的约束与局限性
-
不能是实例化泛型类型
package generic; public class Restrict<T> { private T data; //正确构造方法 public Restrict(T data){ this.data = data;//编译错误 } //错误构造:不能实例化类型变量 public Restrict(){ this.data = new T();//编译错误 } } -
普通静态域(类 与 方法 )中不能引用泛型变量,但泛型方法可以被static 修饰
package generic; public class Restrict<T> { private T data; private static T instance;//编译错误 private static <T >T getInstance;//可以的 }- 为什么:虚拟机在创建对象时,先执行静态域代码,再指定构造代码
-
泛型类型不能是基本类型,但可以使用其包装类型
- double 不是对象,Double 是对象
- Java 并不是严格面向对象(dart 就是严格面向对象的 ),其中有基本类型存在
package generic; public class Restrict<T> { private T data; public static void main(String[] args) { Restrict<double> d;//编译错误 Restrict<Double> D;//编译通过 } } -
不能对泛型使用 instanceOf
- 涉及到泛型擦除;
-
泛型类实例,拿到的字节码是泛型类本身,也叫原生类型
-
示例代码
package generic; public class Restrict<T> { private T data; public static void main(String[] args) { Restrict<Double> D = new Restrict<>(); Restrict<String> S = new Restrict<>(); System.out.println(D.getClass() == S.getClass()); System.out.println(D.getClass().getName()); System.out.println(S.getClass().getName()); } } -
运行截图:
-
-
可以定义泛型数组,但是不能将其实例化
-
实例代码:
-
-
泛型类是不能派生自Exception、Throwable ,且异常中不能捕获泛型对象
- 为什么限定类型可以指定为Throwable
-
但是可以抛出泛型类型的异常 + 此时需要配合try - catch 语句块