java中泛型浅淡
Java中的泛型(Generics)是一种支持泛型编程的工具,它允许程序员在编译时提供类型信息,从而提高代码的复用性和安全性。泛型的应用统一了数据类型,把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,应为在编译阶段类型就能确定下来。
泛型中的细节
- 泛型中不能写基本数据类型(int,float,double,boolean,byte,char,short,long)
- 指定泛型的具体类型后,传递数据时,可以传入该类型和他的子类类型
- 如果不写泛型,类型默认是Object
泛型的种类
- 泛型类:
允许你定义一个类,该类可以操作任意类型的数据,而不需要在代码中使用具体的类型
1 | public class Box<T> { |
- 泛型接口:
允许你定义一个接口,该接口可以操作任意类型的数据
1 | public interface Generate<T> { |
- 泛型方法:
允许你在方法级别指定泛型类型,而不是在类级别
1 | public <T> void printArray(T[] array) { |
- 泛型数组:
Java不允许直接创建泛型数组,但是可以通过数组实例化来间接创建
1 | Integer[] intArray = (Integer[]) new Number[10]; |
泛型的继承和通配符
- 泛型不具备继承性,但是数据具有继承性
假设我们有一个List<Person>
,但我们不能将他赋值给List<Child>
类型,即便Child继承了Person。这是因为List<Person>
和List<Child>
是两个不同的泛型类型,并且在泛型系统中不具备继承关系。
1 | List<Parent> parents = new ArrayList<>(); |
即便泛型类型不支持直接的继承关系,泛型中实际的元素依然可以通过父类来引用。这依赖于对象的继承关系,而不是泛型类型的继承关系。假设你有一个List<Parent>
和一个List<Child>
,虽然它们的类型不具备继承性,但你可以将Child
对象当作Parent
来处理。
1 | List<Parent> parentList = new ArrayList<>(); |
协变与泛型的关系
在一些编程语言(如 C# 和 Kotlin)中,协变(Covariance)概念部分缓解了这个限制。它允许在泛型接口或类的某些上下文中,使List<Child>
可以被视为List<Parent>
。不过,Java 并不允许泛型的协变和逆变直接应用于容器类型,但可以通过通配符(Wildcard)如List<? extends Parent>
来实现一定的协变效果。
泛型的通配符:允许我们指定一个类型可以是任意类型或者任意类型的子类型
- ?
- ? extends E
- ? super E
使用场景
- 定义类,方法,接口的时候,如果类型不能确定,就可以定义泛型
- 如果类型不确定,但是能知道是哪个继承体系中的,可以使用泛型的通配符
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Czar!
评论
ValineDisqus