Java 通用方法赢得';行不通

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

我的泛型方法给出了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").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@SyamS
org.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