gpt4 book ai didi

java - 通用方法不起作用

转载 作者:行者123 更新时间:2023-12-01 13:00:33 27 4
gpt4 key购买 nike

我的通用方法给出了强制转换异常。

java.util.LinkedHashMap cannot be cast to com.example.model.Student

主类

public static void main(String[] args) {
Map<String, Student> students = SampleClass.getStudents("students.json");

System.out.println(students.get("student1").getName());

}

示例类

public static <T> Map<String, T> getStudents(String filename) {
Map<String, T> studentMap = null;

ObjectMapper mapper = new ObjectMapper();
try {
studentMap = mapper.readValue(new File(filename),
new TypeReference<Map<String, T>>() { });
} catch (JsonParseException e) {
System.out.println(e.getMessage());
} catch (JsonMappingException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}

return (Map<String, T>)studentMap;
}

我做错了什么?

更新json 文件

{
"student1" :
{
"name" : "name1",
"age" : 22
},
"student2" :
{
"name" : "name2",
"age" : 22
}
}

更新

找到this作为解决方案。

最佳答案

问题出在你的 TypeReference<Map<String, T>> 上。当你在这里给出 T 时, jackson 将尝试推断类型。由于此时 Jackson 对 Student 类一无所知,因此它推断“name”:“name1”是一个具有键“name”和值“name1”的 LinkedHashMap。因此它又创建了一个 LinkedHashMap<String, LinkedHashMap<String>> .

作为一个快速解决方案,您可以在对象映射器方法中使用 TypeReference 作为

studentMap = mapper.readValue(new File(filename), new TypeReference<Map<String, Student>>() { });

由于该方法是 getStudents,因此使用此 TypeReference 是有意义的,但该方法中泛型的全部意义就被浪费了。

另一种方法是使用自定义反序列化器。有很多方法可以做到这一点。您可以在 http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 找到详细信息

例如,让我们使用自定义反序列化器为所有可能的类创建一个标记接口(interface)。假设我们有一个接口(interface) StudentI,它将由您键入 T 可能拥有的所有可能的类实现。然后使用 @JsonTypeInfo 提供有关该类的其他详细信息

学生界面

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;


@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@Type(value = Student.class, name = "student") })
public interface StudentI {

}

这意味着如果您在 json 中给出类似“type : Student”的内容,映射器将为您使用 Student.class。

示例类

import java.io.File;
import java.io.IOException;
import java.util.Map;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SampleClass {

public static <T extends StudentI> Map<String, T> getStudents(String filename) {
Map<String, T> studentMap = null;

ObjectMapper mapper = new ObjectMapper();
try {
studentMap = mapper.readValue(new File(filename),
new TypeReference<Map<String, StudentI>>() { });
} catch (JsonParseException e) {
System.out.println(e.getMessage());
} catch (JsonMappingException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}

return (Map<String, T>)studentMap;
}

}

Students.json

{
"student1" :
{
"name" : "name1",
"age" : 22,
"type" : "student"
},
"student2" :
{
"name" : "name2",
"age" : 22,
"type" : "student"
}
}

现在你的 Student 类应该实现这个接口(interface)

public class Student implements StudentI {
private String name;
private int age;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}

完成此操作后,您的代码将按预期工作

public static void main(String[] args) {
Map<String, Student> students = SampleClass.getStudents("students.json");
System.out.println(students.get("student1").getName());
}

//Output : name1

关于java - 通用方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23547674/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com