Java泛型:类型安全的编程利器
Java泛型:类型安全的编程利器
概述
泛型是Java 5引入的重要特性,它允许在定义类、接口和方法时使用类型参数。泛型提供了编译时的类型安全检查,避免了强制类型转换的麻烦。
1. 泛型类
// 通用容器类
public class Box<T> {
private T content;
public Box(T content) {
this.content = content;
}
public T getContent() {
return content;
}
public void setContent(T content) {
this.content = content;
}
@Override
public String toString() {
return "Box[" + content + "]";
}
}
// 使用泛型类
Box<String> stringBox = new Box<>("Hello");
Box<Integer> intBox = new Box<>(123);
2. 泛型方法
public class GenericMethods {
// 泛型方法
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
// 多个类型参数
public static <K, V> Map<K, V> createMap(K key, V value) {
Map<K, V> map = new HashMap<>();
map.put(key, value);
return map;
}
public static void main(String[] args) {
Integer[] integers = {1, 2, 3, 4, 5};
String[] strings = {"Java", "Python", "C++"};
printArray(integers);
printArray(strings);
Map<String, Integer> map = createMap("age", 25);
}
}
3. 泛型接口
// 泛型接口
public interface Repository<T> {
T findById(Long id);
List<T> findAll();
void save(T entity);
void delete(T entity);
}
// 实现泛型接口
public class UserRepository implements Repository<User> {
private Map<Long, User> store = new HashMap<>();
@Override
public User findById(Long id) {
return store.get(id);
}
@Override
public List<User> findAll() {
return new ArrayList<>(store.values());
}
@Override
public void save(User entity) {
store.put(entity.getId(), entity);
}
@Override
public void delete(User entity) {
store.remove(entity.getId());
}
}
4. 类型通配符
// 无界通配符
public static void printList(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
// 上界通配符(? extends)
public static double sumOfList(List<? extends Number> list) {
double sum = 0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
// 下界通配符(? super)
public static void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
list.add(3);
}
5. PECS原则
// Producer Extends, Consumer Super
public class PECSDemo {
public static void copy(List<? extends Number> src, List<? super Number> dest) {
for (Number item : src) {
dest.add(item);
}
}
public static void fill(List<? super String> list, String value, int count) {
for (int i = 0; i < count; i++) {
list.add(value);
}
}
}
6. 类型擦除
// 泛型在编译后会被擦除
public class TypeErasure<T> {
private T data;
public T getData() {
return data;
}
// 编译后变成:public Object getData()
}
// 获取泛型类型信息
class StringList extends ArrayList<String> {}
public class GenericReflection {
public static void main(String[] args) {
ParameterizedType type = (ParameterizedType)
StringList.class.getGenericSuperclass();
Type[] actualTypes = type.getActualTypeArguments();
System.out.println(actualTypes[0]); // class java.lang.String
}
}
最佳实践
- 使用泛型提高类型安全:避免使用原始类型
- 合理使用通配符:遵循PECS原则
- 限制泛型边界:使用extends约束泛型类型
- 避免类型擦除陷阱:不能创建泛型数组
- 使用@SafeVarargs:避免泛型可变参数警告
总结
泛型是Java编程的重要特性,它提供了编译时类型安全检查,减少了强制类型转换。掌握泛型的使用,可以编写出更加安全、灵活和可复用的代码。