Java 通用方法赢得';行不通
我的泛型方法给出了casting异常 无法将java.util.LinkedHashMap强制转换为com.example.model.Student 主类Java 通用方法赢得';行不通,java,generics,map,jackson,generic-method,Java,Generics,Map,Jackson,Generic Method,我的泛型方法给出了casting异常 无法将java.util.LinkedHashMap强制转换为com.example.model.Student 主类 public static void main(String[] args) { Map<String, Student> students = SampleClass.getStudents("students.json"); System.out.println(students.get("student1
public static void main(String[] args) {
Map<String, Student> students = SampleClass.getStudents("students.json");
System.out.println(students.get("student1").getName());
}
更新
作为解决方案找到。取决于json文件中的内容。看起来映射程序返回的是学生对象而不是地图。问题在于您的
类型引用。当你在这里给T时,jackson会试图推断出它的类型。因为此时jackson对Student类一无所知,所以推断“name”:“name1”是一个带有键“name”和值“name1”的LinkedHashMap。因此,它反过来会创建一个链接地图
作为一个快速解决方案,您可以使用对象映射器方法中的TypeReference作为
studentMap = mapper.readValue(new File(filename), new TypeReference<Map<String, Student>>() { });
这意味着,如果您在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;
}
}
现在,您的学生类应该实现这个接口
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
publicstaticvoidmain(字符串[]args){
Map students=SampleClass.getStudents(“students.json”);
System.out.println(students.get(“student1”).getName();
}
//输出:name1
您能指出它在哪一行吗?你为什么要在getStudents()
的末尾使用studentMap
?我认为您可能必须指定T
:SampleClass.getStudents(“students.json”)
异常在System.out.println(students.get(“student1”).getName()抛出代码>行您的ObjectMapper是什么?mapper.readValue()可能返回的是映射,而不是Map@SyamSorg.codehaus.jackson.map.ObjectMapper
异常说明了不同的情况:映射程序似乎返回了一个包含LinkedHashMap
的映射,而不是预期的Student
。我这样做了。还可以根据添加@JsonTypeName(“学生”)
。但是give error无法将类型id“name”解析为[simple type,class com.example.model.StudentI]的子类型。
您的代码没有太大变化。只要添加@JsonTypeName(“学生”)
我就更新了更改。我没有更改json文件,这很奇怪,您提到的方式对我来说很好。但是,如果您没有在json中提供类型信息,它将抛出一个不同的错误。你用的是哪个版本的jackson?谢谢Syam。正如我在几个地方看到的那样,你的方法应该有效。但我的没用。无论如何,我找到了答案
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;
}
}
{
"student1" :
{
"name" : "name1",
"age" : 22,
"type" : "student"
},
"student2" :
{
"name" : "name2",
"age" : 22,
"type" : "student"
}
}
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