泛型程序设计详解
泛型程序设计
使用泛型程序设计的程序设计的好处
避免继承的强制类型转化
对于集合来说可以保证统一的类型
简单泛型类
public class pair<T, U>{
private T first;
private U second;
public pair(){...};
public pair(T first, T second){...};
}//T,U表示pair类中字段可用的类型
泛型方法
class ArrayAlg {
public static <T, U> T getMiddle(T...a) {//<T, U>类型变量表示参数中可用的类型
return a[a.length / 2];
}
}
类型变量的限定
public static <T enxtends U [& M...] > T func(T t)
,这里的限定为T必须继承U、M…类型
泛型代码和虚拟机
虚拟机没有泛型对象——所有对象都属于普通类。
-
类型擦除
无论何时第一一个泛型类型,都会自动提供一个相应的原始类型,有限定返回限定类型,没有则返回object类型
public class pair<T, U>{ private T first; private U second; public pair(){...}; public pair(T first, T second){...}; }//T,U表示pair类中字段可用的类型
擦除后
public class pair<Object, Object>{ private Object first; private Object second; public pair(){...}; public pair(Object first, Object second){...}; }//T,U表示pair类中字段可用的类型
-
转换泛型表达式
擦除了返回类型,编译器会在调用原始方法后自动进行强制类型转换
-
转换泛型方法
擦除一些变量的类型后,要调用变量的方法,
JVM
提供了桥方法来实现
限制与局限性
- 不能用基本类型实例化类型参数
- 运行是类型查询只适用于原始类型(
instanceof
) - 不能创建参数化类型的数组
Varargs
警告:对于可变参数形成的数组不会报错,只会警告。可以通过@SafeVarags
来取消警告- 不能实例化(new)泛型类型变量
- 不能实例化(new)泛型数组
- 泛型类的静态上下文中类型变量无效
- 不能抛出或不会泛型类的实例
- 可以取消对检查型异常的检查
- 注意擦除后的冲突
泛型类型的继承原则
T是U的子类, 但Pair[T]不是Pair[U]的子类
通配符类型
-
概念:在通配符类型中,允许参数发生改变
Pair< ? extends T>
只要求参数是T的子类
-
通配符的超类型限定
? super T
限制为T的所有超类
-
无限定的通配符 ?
Pair<?> 与Pair得不同点在于可以用任意Object对象调用原始Pair类的方法
-
通配符捕获
在含通配符的泛型方法中构造一个不含通配符的方法,该方法可以用泛型变量捕获通配符对之进行操作
Pair<?> 与Pair得不同点在于可以用任意Object对象调用原始Pair类的方法
-
通配符捕获
在含通配符的泛型方法中构造一个不含通配符的方法,该方法可以用泛型变量捕获通配符对之进行操作
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!