Java案例如何使用泛型编程?

wen java案例 9

本文目录导读:

Java案例如何使用泛型编程?

  1. Java泛型编程实战案例
  2. 泛型使用最佳实践

Java泛型编程实战案例

泛型是Java中非常重要的特性,它允许在编译时进行类型检查,提高代码的复用性和安全性,下面通过几个典型案例来展示泛型的实际应用。

泛型类 - 通用容器实现

// 泛型类定义
public class GenericBox<T> {
    private T content;
    public GenericBox(T content) {
        this.content = content;
    }
    public T getContent() {
        return content;
    }
    public void setContent(T content) {
        this.content = content;
    }
    public boolean isEmpty() {
        return content == null;
    }
    @Override
    public String toString() {
        return "Box contains: " + content;
    }
    // 使用示例
    public static void main(String[] args) {
        // 存储字符串
        GenericBox<String> stringBox = new GenericBox<>("Hello");
        System.out.println(stringBox);
        // 存储整数(自动装箱)
        GenericBox<Integer> integerBox = new GenericBox<>(42);
        System.out.println(integerBox);
        // 存储自定义对象
        GenericBox<List<String>> listBox = new GenericBox<>(Arrays.asList("A", "B"));
        System.out.println(listBox);
    }
}

泛型方法 - 通用排序算法

public class GenericSort {
    // 泛型方法:对任意类型数组进行排序
    public static <T extends Comparable<T>> void sort(T[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = i + 1; j < array.length; j++) {
                if (array[i].compareTo(array[j]) > 0) {
                    T temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
    }
    // 泛型方法:打印数组
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
    // 使用示例
    public static void main(String[] args) {
        // 排序整数数组
        Integer[] intArray = {3, 1, 4, 1, 5, 9};
        System.out.println("排序前:");
        printArray(intArray);
        sort(intArray);
        System.out.println("排序后:");
        printArray(intArray);
        // 排序字符串数组
        String[] strArray = {"banana", "apple", "cherry", "date"};
        System.out.println("\n排序前:");
        printArray(strArray);
        sort(strArray);
        System.out.println("排序后:");
        printArray(strArray);
    }
}

泛型接口 - 数据仓库模式

// 泛型接口
public interface Repository<T, ID> {
    T findById(ID id);
    List<T> findAll();
    void save(T entity);
    void delete(T entity);
    void deleteById(ID id);
}
// 实现泛型接口 - 用户仓库
public class UserRepository implements Repository<User, Long> {
    private Map<Long, User> userDatabase = new HashMap<>();
    private static long idCounter = 1;
    @Override
    public User findById(Long id) {
        return userDatabase.get(id);
    }
    @Override
    public List<User> findAll() {
        return new ArrayList<>(userDatabase.values());
    }
    @Override
    public void save(User entity) {
        if (entity.getId() == null) {
            entity.setId(idCounter++);
        }
        userDatabase.put(entity.getId(), entity);
    }
    @Override
    public void delete(User entity) {
        userDatabase.remove(entity.getId());
    }
    @Override
    public void deleteById(Long id) {
        userDatabase.remove(id);
    }
}
// 用户实体类
public class User {
    private Long id;
    private String name;
    private String email;
    // 构造器、getter/setter省略
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
    }
    // 使用示例
    public static void main(String[] args) {
        UserRepository userRepo = new UserRepository();
        // 创建用户
        User user1 = new User("张三", "zhangsan@example.com");
        User user2 = new User("李四", "lisi@example.com");
        // 保存用户
        userRepo.save(user1);
        userRepo.save(user2);
        // 查询所有用户
        System.out.println("所有用户:");
        userRepo.findAll().forEach(System.out::println);
        // 根据ID查询
        System.out.println("\n查找ID为1的用户:" + userRepo.findById(1L));
    }
}

通配符 - 灵活的数据处理

public class WildcardDemo {
    // 使用通配符处理不同类型的集合
    public static void processNumbers(List<? extends Number> numbers) {
        double sum = 0;
        for (Number num : numbers) {
            sum += num.doubleValue();
        }
        System.out.println("Sum: " + sum);
    }
    // 上界通配符 - 只能读取,不能写入
    public static void printList(List<?> list) {
        for (Object obj : list) {
            System.out.print(obj + " ");
        }
        System.out.println();
    }
    // 下界通配符 - 可以写入特定类型
    public static void addIntegers(List<? super Integer> list) {
        list.add(1);
        list.add(2);
        list.add(3);
    }
    public static void main(String[] args) {
        // 上界通配符示例
        List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
        List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3);
        processNumbers(intList);     // 可以处理Integer列表
        processNumbers(doubleList);  // 也可以处理Double列表
        // 下界通配符示例
        List<Number> numberList = new ArrayList<>();
        addIntegers(numberList);     // 可以向Number列表添加Integer
        System.out.println("Number列表内容:");
        printList(numberList);
    }
}

类型擦除与桥接方法

// 演示类型擦除机制
public class TypeErasureDemo<T> {
    private T value;
    public TypeErasureDemo(T value) {
        this.value = value;
    }
    public T getValue() {
        return value;
    }
    public void setValue(T value) {
        this.value = value;
    }
    // 编译后的等价代码(类型擦除后)
    // public class TypeErasureDemo {
    //     private Object value;
    //     
    //     public TypeErasureDemo(Object value) {
    //         this.value = value;
    //     }
    //     
    //     public Object getValue() {
    //         return value;
    //     }
    //     
    //     public void setValue(Object value) {
    //         this.value = value;
    //     }
    // }
    public static void main(String[] args) {
        // 运行时类型检查
        TypeErasureDemo<String> demo1 = new TypeErasureDemo<>("Hello");
        TypeErasureDemo<Integer> demo2 = new TypeErasureDemo<>(42);
        // 无法在运行时区分具体类型
        System.out.println(demo1.getClass() == demo2.getClass()); // 输出: true
        // 使用反射验证类型擦除
        try {
            java.lang.reflect.Field field = TypeErasureDemo.class.getDeclaredField("value");
            System.out.println("字段类型: " + field.getType().getName()); // 输出: java.lang.Object
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

高级应用 - 泛型工厂模式

// 泛型工厂接口
public interface GenericFactory<T> {
    T create();
    T create(Object... args);
}
// 具体实现
public class UserFactory implements GenericFactory<User> {
    @Override
    public User create() {
        return new User("默认用户", "default@example.com");
    }
    @Override
    public User create(Object... args) {
        if (args.length >= 2 && args[0] instanceof String && args[1] instanceof String) {
            return new User((String) args[0], (String) args[1]);
        }
        return create(); // 默认创建
    }
    public static void main(String[] args) {
        GenericFactory<User> userFactory = new UserFactory();
        // 创建默认用户
        User defaultUser = userFactory.create();
        System.out.println("默认用户: " + defaultUser);
        // 创建自定义用户
        User customUser = userFactory.create("王五", "wangwu@example.com");
        System.out.println("自定义用户: " + customUser);
    }
}

泛型使用最佳实践

  1. 优先使用泛型:尽量使用泛型而不是Object类型
  2. 限制类型范围:使用有界类型参数(如<T extends Comparable<T>>
  3. PECS原则:Producer Extends, Consumer Super
  4. 避免混合使用:不要在同一方法中混用原始类型和泛型
  5. 注意类型擦除:理解泛型在运行时的限制
  6. 使用@SuppressWarnings注解:仅在必要时抑制未检查警告

这些案例展示了泛型在实际开发中的多种应用场景,帮助你更好地理解和运用泛型编程。

抱歉,评论功能暂时关闭!