Java泛型
泛型简介
泛型是Java 5引入的一个重要特性,它允许在定义类、接口和方法时使用类型参数。泛型的主要目的是提供编译时类型安全,并消除类型转换的需要。
泛型的基本概念
// 泛型类定义
public class Box {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 使用泛型类
Box stringBox = new Box<>();
stringBox.setContent("Hello");
String message = stringBox.getContent();
泛型类
泛型类是在类定义时使用类型参数的类。
// 泛型类示例
public class Pair {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public void setKey(K key) {
this.key = key;
}
public void setValue(V value) {
this.value = value;
}
}
// 使用泛型类
Pair pair = new Pair<>("age", 25);
String key = pair.getKey();
Integer value = pair.getValue();
泛型方法
泛型方法是在方法定义时使用类型参数的方法。
// 泛型方法示例
public class ArrayUtils {
public static void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static T getFirst(T[] array) {
return array.length > 0 ? array[0] : null;
}
}
// 使用泛型方法
String[] names = {"Alice", "Bob", "Charlie"};
ArrayUtils.swap(names, 0, 2);
String first = ArrayUtils.getFirst(names);
有界类型参数
有界类型参数允许限制泛型类型参数的范围。
// 有界类型参数示例
public class NumberBox {
private T number;
public NumberBox(T number) {
this.number = number;
}
public double getDoubleValue() {
return number.doubleValue();
}
public int getIntValue() {
return number.intValue();
}
}
// 使用有界类型参数
NumberBox intBox = new NumberBox<>(42);
NumberBox doubleBox = new NumberBox<>(3.14);
// 编译错误:String不是Number的子类
// NumberBox stringBox = new NumberBox<>("error");
通配符
通配符用于表示未知类型,使泛型更加灵活。
// 通配符示例
public class WildcardExample {
// 上界通配符
public static double sumOfList(List extends Number> list) {
double sum = 0.0;
for (Number number : list) {
sum += number.doubleValue();
}
return sum;
}
// 下界通配符
public static void addNumbers(List super Integer> list) {
list.add(1);
list.add(2);
list.add(3);
}
}
// 使用通配符
List integers = Arrays.asList(1, 2, 3);
List doubles = Arrays.asList(1.1, 2.2, 3.3);
double sum1 = WildcardExample.sumOfList(integers);
double sum2 = WildcardExample.sumOfList(doubles);
List numbers = new ArrayList<>();
WildcardExample.addNumbers(numbers);
泛型接口
泛型接口允许在接口定义时使用类型参数。
// 泛型接口示例
public interface Comparable {
int compareTo(T other);
}
// 实现泛型接口
public class Person implements Comparable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return this.age - other.age;
}
}
实践练习
练习1:实现泛型栈
public class Stack{ private List elements; public Stack() { elements = new ArrayList<>(); } public void push(T element) { elements.add(element); } public T pop() { if (isEmpty()) { throw new EmptyStackException(); } return elements.remove(elements.size() - 1); } public T peek() { if (isEmpty()) { throw new EmptyStackException(); } return elements.get(elements.size() - 1); } public boolean isEmpty() { return elements.isEmpty(); } public int size() { return elements.size(); } }