← 返回首页

Java泛型:类型安全的编程利器

📂 java ⏱ 3 min 411 words

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
    }
}

最佳实践

  1. 使用泛型提高类型安全:避免使用原始类型
  2. 合理使用通配符:遵循PECS原则
  3. 限制泛型边界:使用extends约束泛型类型
  4. 避免类型擦除陷阱:不能创建泛型数组
  5. 使用@SafeVarargs:避免泛型可变参数警告

总结

泛型是Java编程的重要特性,它提供了编译时类型安全检查,减少了强制类型转换。掌握泛型的使用,可以编写出更加安全、灵活和可复用的代码。