【技术积累】Java中的泛型【一】
泛型是什么Java中的泛型是一种能够让用户在编写代码时避免使用明确的类型而进行类型参数化的机制。Java中的泛型可以让编程者在代码编写时不必关心具体类型,只用关心类型之间的关系和相互转换,从而在编写代码的过程中实现类型的复用。这使得代码更加简洁、可读性更高,并且可以提高代码的可维护性和可扩展性。
Java泛型可以在类、方法、接口、以及数组等多个地方使用,并且可以结合约束条件来限制类型参数的类型。例如,在定义一个泛型类时,可以使用定义一个泛型类型参数,T可以代表任何具体类型,例如Integer、String、Map等。在使用泛型时,可以将具体类型传递给类型参数,然后在方法或者类中使用该类型参数,从而实现代码的类型自动化。
Java中的泛型还具有类型检查和类型擦除的特性。类型检查可以检查在编译时期是否使用了正确的类型,避免了在运行时期由于类型转换错误而产生的异常。而类型擦除则是Java泛型在实现时使用的一种技术,它会去掉泛型中的类型参数信息,并将其变为原始类型,在运行时也不会保留泛型的信息,从而实现Java泛型的运行时兼容性。
什么是类型参数?
Java中的类型参数是用于泛型编程的占位符,可以用来表示任何类型。它们用尖括号 "" 括起来,放置在类名或方法名后面,用来指定通用类型。 例如,以下代码中的 T 就是一个类型参数: public class MyClass<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
} 在上面的代码中,T 代表一个通用类型。可以在创建 MyClass 对象时指定 T 的具体类型,如: MyClass<Integer> intObj = new MyClass<>();
MyClass<String> strObj = new MyClass<>();这样,intObj 对象中的 value 的类型就是 Integer,strObj 对象中的 value 的类型就是 String。 类型参数可以用在类、方法、接口等地方,用来实现通用的算法。使用类型参数可以允许我们编写一次通用的代码,可以用于不同类型的数据,是 Java 泛型编程的核心特性。什么是类型擦除?
类型擦除(type erasure)是指在Java编译期间,对泛型类型参数信息的擦除,将所有泛型类型参数都用它们的上界(或Object类型)替换,从而在运行时不会保留泛型类型信息。具体来说,编译器会将泛型类、泛型接口中的类型参数用对应的类型上限(即extends关键字后面的类型)替换,泛型方法中的类型参数也会被替换。例如,对于以下泛型类:public class Pair<T, S> {
private T first;
private S second;
public Pair(T first, S second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public S getSecond() {
return second;
}
}它在编译后会被转换为:public class Pair {
private Object first;
private Object second;
public Pair(Object first, Object second) {
this.first = first;
this.second = second;
}
public Object getFirst() {
return first;
}
public Object getSecond() {
return second;
}
}这就是类型擦除的过程,所有泛型类型信息都被擦除并替换为Object类型。虽然泛型类型信息被擦除,但在运行时可以通过反射机制获取到泛型类型信息,这使得泛型在运行时仍然可以使用。但是,由于类型擦除,泛型类型参数在运行时无法进行类型检查,因此可能会导致类型安全问题。什么是通配符类型?
Java中的通配符类型是一种泛型类型,用于表示未知类型的泛型参数。 通配符类型由问号(?)表示,其可以用作方法的参数类型、字段类型、局部变量类型等任何地方需要使用泛型类型的地方。
通配符类型有两种形式:无界通配符类型和有界通配符类型。
无界通配符类型是指使用符号 ? 表示未知类型,例如 List。在使用无界通配符类型时,不能添加任何元素到集合中,因为这个集合的元素类型是未知的。但是,可以从集合中获取元素,并将其转换为 Object 类型。
有界通配符类型是指使用符号 ? extends 或 ? super,限制泛型参数的类型范围。例如,List 表示List中可以存放任何类型的对象,相当于是List的简化写法。
无限定通配符可以用于以下情况:
[*]当泛型参数类型并不重要时,比如在方法中只需要对泛型参数进行处理而不需要知道具体类型。
[*]当泛型类型的上界或下界无法确定时,比如在方法中需要接受不同类型的List对象,但是这些List对象的元素类型并不确定。
无限定通配符并不能直接调用参数的方法或者添加新的元素,因为其具体的类型是未知的,需要通过强制类型转换才能进行操作。
什么是类型边界
Java泛型中的类型边界(Type Bound)是指限制泛型类型参数的范围,使得参数只能是特定类或其子类,或者实现了特定接口的类或其实现类。
类型边界有两种形式:extends和super。extends用于限制类型参数的上界(Upper Bound),即指定参数只能是某一类或其子类的类型;super用于限制类型参数的下界(Lower Bound),即指定参数只能是某一类或其父类的类型。
public static <T> void printArray(T[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array + " ");
}
System.out.println();
}什么是协变
Java泛型中的协变(Covariant)是指泛型类型参数的子类型关系能够被继承到泛型类的实例化类型中。也就是说,子类型的泛型类实例可以替代父类型的泛型类实例。
在Java中,协变类型只有在泛型参数是用作方法返回值类型时才可以生效。在这种情况下,如果泛型实例可以返回子类型对象,则该类型为协变类型。
public class Animal {}public class Dog extends Animal {}//泛型协变public class GenericClass {public T getAnimal() {return null;}}GenericClass dogClass = new GenericClass();GenericClass
页:
[1]