色空大师 2025-05-19 09:48 采纳率: 42.3%
浏览 14

list集合使用object接受时,再次转化为list集合会报错ClassCastException

list集合使用object接受时,再次转化为list集合会报错ClassCastException

代码如下;
用户类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable{

    private static final long serialVersionUID = 1L;
    private String name;
    private Integer age;


}

测试类


public class Test01 {
    public static void main(String[] args) {

        User u1 = new User("Alice",12);
        User u2 = new User("Bob",25);
        List<User> users = new ArrayList<>();
        users.add(u1);
        users.add(u2);
        Object rawData =List.of(users);

        //Object rawData模拟为需要转化的结果
        List<User> userList = (List<User>)rawData;

        System.out.println("userList" + userList);
        for (User user : userList) {
            System.out.println(user.getName() + ", " + user.getAge());
        }
    }

结果如下


userList[[User(name=Alice, age=12), User(name=Bob, age=25)]]
Exception in thread "main" java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class org.example.entity.User (java.util.ArrayList is in module java.base of loader 'bootstrap'; org.example.entity.User is in unnamed module of loader 'app')
    at org.example.test.Test01.main(Test01.java:24)

Process finished with exit code 1

  • 写回答

6条回答 默认 最新

  • 檀越@新空间 2025-05-19 09:49
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    问题分析

    在你的代码中,List.of() 方法返回的是一个不可变的 List 实例,并且它的类型是 List<?>。当你尝试将 Object 类型的变量 rawData 转换回 List<User> 时,出现了 ClassCastException。这是因为 List.of() 返回的 List 是一个不可变的集合,其运行时类型并不是 ArrayList 或其他你期望的具体实现类。

    此外,List.of() 创建的集合是不可变的,而你在后续代码中试图对其进行修改(例如添加元素),这也会导致运行时异常。


    解决方案

    以下是解决该问题的几种方法:

    方法 1:直接使用原始集合对象

    如果你已经有一个 List<User> 对象,可以直接使用它,而不是通过 List.of() 创建新的集合。这样可以避免类型转换问题。

    public class Test01 {
        public static void main(String[] args) {
    
            User u1 = new User("Alice", 12);
            User u2 = new User("Bob", 25);
            List<User> users = new ArrayList<>();
            users.add(u1);
            users.add(u2);
    
            // 直接使用原始集合对象
            List<User> userList = users;
    
            System.out.println("userList" + userList);
            for (User user : userList) {
                System.out.println(user.getName() + ", " + user.getAge());
            }
        }
    }
    

    优点:避免了类型转换和不可变集合的问题。 缺点:不适用于需要从其他来源获取集合的情况。


    方法 2:使用 List.copyOf() 转换集合

    如果你确实需要创建一个新的不可变集合,可以使用 List.copyOf() 方法。这样可以确保类型安全。

    public class Test01 {
        public static void main(String[] args) {
    
            User u1 = new User("Alice", 12);
            User u2 = new User("Bob", 25);
            List<User> users = new ArrayList<>();
            users.add(u1);
            users.add(u2);
    
            // 使用 List.copyOf 创建不可变集合
            List<User> immutableList = List.copyOf(users);
    
            // 如果需要可变集合,可以重新创建
            List<User> mutableList = new ArrayList<>(immutableList);
    
            System.out.println("mutableList" + mutableList);
            for (User user : mutableList) {
                System.out.println(user.getName() + ", " + user.getAge());
            }
        }
    }
    

    优点

    • List.copyOf() 确保集合是不可变的,适合用于只读场景。
    • 可以通过 new ArrayList<>(immutableList) 创建一个新的可变集合。

    缺点:需要额外的步骤来处理不可变集合。


    方法 3:强制类型转换并检查类型

    如果你必须使用 List.of(),可以在类型转换前检查对象的实际类型是否为 List<User>

    public class Test01 {
        public static void main(String[] args) {
    
            User u1 = new User("Alice", 12);
            User u2 = new User("Bob", 25);
            List<User> users = new ArrayList<>();
            users.add(u1);
            users.add(u2);
    
            // 使用 List.of() 创建不可变集合
            Object rawData = List.of(users);
    
            // 检查类型并进行安全转换
            if (rawData instanceof List<?>) {
                List<?> rawList = (List<?>) rawData;
                List<User> userList = rawList.stream()
                                             .map(item -> (User) item)
                                             .collect(Collectors.toList());
    
                System.out.println("userList" + userList);
                for (User user : userList) {
                    System.out.println(user.getName() + ", " + user.getAge());
                }
            } else {
                System.out.println("rawData is not a List");
            }
        }
    }
    

    优点:通过类型检查避免了直接的 ClassCastException缺点:增加了代码复杂性,并且仍然可能抛出 ClassCastException


    方法 4:使用泛型和类型安全的集合

    如果你希望避免类型转换问题,可以在设计时就使用泛型,确保集合的类型始终正确。

    public class Test01 {
        public static void main(String[] args) {
    
            User u1 = new User("Alice", 12);
            User u2 = new User("Bob", 25);
    
            // 使用泛型定义集合类型
            List<User> users = new ArrayList<>();
            users.add(u1);
            users.add(u2);
    
            System.out.println("users" + users);
            for (User user : users) {
                System.out.println(user.getName() + ", " + user.getAge());
            }
        }
    }
    

    优点:完全避免了类型转换问题。 缺点:需要在设计时就明确集合的类型。


    总结

    在 Java 中,List.of() 返回的是不可变集合,其运行时类型与具体实现类不同,因此不能直接将其转换为具体的泛型集合类型。推荐的解决方案是直接使用原始集合对象或通过 List.copyOf() 创建不可变集合,并根据需求选择合适的集合类型。如果必须使用 List.of(),则需要进行类型检查以避免 ClassCastException

    最终推荐方案:方法 1 或方法 4。

    评论

报告相同问题?

问题事件

  • 创建了问题 5月19日