Java泛型详解
什么是泛型?
泛型主要体现在类和方法中,用于实现在编译时期进行类型检查和类型推断的功能,从而避免了在运行时出现类型转换的错误。
泛型类
泛型类是指在类的定义中使用了泛型,即类中的属性、方法等都可以使用泛型。泛型类的语法格式如下:
class ClassName<T1, T2, ...> {
//属性的类型也可以使用泛型
T1 attribute1;
T2 attribute2;
public void methodName(T1 param1, T2 param2, ...) {
//方法中也可以使用泛型
}
}
在泛型类中,T1、T2、... 可以是任何标识符,但建议在命名上遵循驼峰命名法。
下面是一个使用泛型类的示例:
class Pair<T1, T2> {
private final T1 first;
private final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public T1 getFirst() {
return first;
}
public T2 getSecond() {
return second;
}
}
// 使用
Pair<String,Integer> pair = new Pair<>("key", 1);
泛型方法
泛型方法是指在方法的定义中使用泛型,即参数、返回值等都可以使用泛型。泛型方法的语法格式如下:
public <T> returnType methodName(T param1, ...) {
//泛型方法的方法体
}
在泛型方法中,<T>
表示声明了一个类型变量 T,可以在方法中使用。
下面是一个使用泛型方法的示例:
public class Util {
public static <T> T getFirst(List<T> list) {
if (list == null || list.isEmpty()) {
return null;
} else {
return list.get(0);
}
}
}
// 使用
List<String> list = new ArrayList<>();
list.add("hello");
String first = Util.getFirst(list);
泛型通配符
泛型通配符可以用来表示一种不确定的泛型类型。在Java中,有两种泛型通配符:?
和 ? extends/subclass
。
?
通配符
?
通配符表示匹配任意类型。例如,List<?> 可以匹配 List
? extends/subclass
通配符
? extends/subclass
通配符表示匹配某个类的子类,或实现了某个接口的类。例如,List<? extends Number> 可以匹配 List
通配符的限制
通配符的使用也有一些限制:
- 通配符只能在类泛型或方法泛型中使用,不能单独使用。
- 泛型中的通配符不能用于泛型类的构造方法、静态方法和静态属性中。
- 通配符的使用除了可以用于参数类型、返回类型外,还可以用于局部变量和成员变量的类型。
泛型擦除
Java中的泛型是通过泛型擦除来实现的。在编译时期,所有使用泛型的地方都会被擦除,替换成相应的非泛型代码。例如,泛型类 Pair<T1,T2> 编译后会变成 Pair<Object,Object>。
泛型擦除的实现会导致以下几个问题:
- 泛型类或泛型方法不能使用基本类型作为类型参数。
- 不能在泛型类中使用
instanceof
操作符判断泛型类型。 - 不能创建泛型类型的数组,如
new T[]
。 - 不能在泛型类型中直接使用
Class
类型。
泛型推断
Java7中引入了泛型推断机制,即diamond
操作符<>
。通过<>
可以省略类型参数,并在编译时根据上下文自动推断出类型。例如:
// 旧的方式
Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();
// 新的方式
Map<String, List<Integer>> map = new HashMap<>();
这样使代码更加简洁,可读性更好。
总结
本文主要讲解了Java泛型的相关知识,包括泛型类、泛型方法、泛型通配符、泛型擦除和泛型推断等内容。泛型是Java的一个重要特性,具有很高的灵活性和可扩展性,在实际开发中应用广泛。
示例
泛型类
public class Test {
public static void main(String[] args) {
Pair<String, Integer> pair = new Pair<>("key", 1);
String first = pair.getFirst();
Integer second = pair.getSecond();
System.out.println("first: " + first + ", second: " + second);
}
}
class Pair<T1, T2> {
private final T1 first;
private final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public T1 getFirst() {
return first;
}
public T2 getSecond() {
return second;
}
}
泛型方法
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
String first = Util.getFirst(list);
System.out.println("first: " + first);
}
}
class Util {
public static <T> T getFirst(List<T> list) {
if (list == null || list.isEmpty()) {
return null;
} else {
return list.get(0);
}
}
}
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 泛型详解(超详细的java泛型方法解析) - Python技术站