Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从映射中获取字段类型_Java_Json_Jackson - Fatal编程技术网

Java 从映射中获取字段类型

Java 从映射中获取字段类型,java,json,jackson,Java,Json,Jackson,我在jsonString字段中有一个json字符串,我正在使用ObjectMapper String jsonString = {"age":12,"location":"UK","gender":"male"}; ObjectMapper mapper = new ObjectMapper(); Map map = mapper.readValue(jsonString, Map.class); 有没有一种方法可以从映射中检索字段类型,而不是使用Pojo类。例如,age是integer类型

我在jsonString字段中有一个json字符串,我正在使用ObjectMapper

String jsonString = {"age":12,"location":"UK","gender":"male"};

ObjectMapper mapper = new ObjectMapper();
Map map = mapper.readValue(jsonString, Map.class);
有没有一种方法可以从映射中检索字段类型,而不是使用Pojo类。例如,age是integer类型,gender是string类型,它不涉及使用Pojo类,而是使用Map类?谢谢

是的,只需呼叫即可(映射器来自com.fasterxml.jackson.databind.ObjectMapper)


你可以这样做。但您需要将对象类型转换为有效类型

    String jsonString = "{\"age\":12,\"location\":\"UK\",\"gender\":\"male\"}";

    ObjectMapper mapper = new ObjectMapper();
    try {
        Map map = mapper.readValue(jsonString, Map.class);
        System.out.println(map);
        Integer age = (int)map.get("age");
        System.out.println(age);
        System.out.println(map.get("age").getClass());
    }catch (IOException|NullPointerException e){}
可以使用getClass()方法获取类型


JSON是一种非类型化语言。这里有两种情况:

情况#1:您知道这些字段应该具有什么类型,并且希望以安全的方式与值交互

在这种情况下,您需要将强制转换硬编码为您知道应该存在的类型,或者您应该创建一个POJO类来进行反序列化。(如果该类仅在小范围内使用,则可以在使用该类的函数中使用私有类,甚至可以使用本地类。)在任何情况下,
mapper.readValue()
,或者如果数据不匹配,代码将引发异常。您需要捕获此异常或传播到调用方。到底什么类型的故障在这里有意义实际上取决于您的应用程序,但是有许多可能的故障

情况#2:您不知道这些字段应该具有什么类型,您希望发现要与之交互的值的类型

不幸的是,没有静态可验证的方式与运行时之前未知的类型进行交互。(这基本上是静态类型系统和动态类型系统之间的区别的定义。)在实践中,使用JSON反序列化的数据,所有内容要么是
数字
字符串
列表
映射
,要么是
。因此,您需要处理这些情况,但即使在
列表中,您也无法在不循环和检查每个元素的情况下知道每个元素的类型,而且您可以用来表示列表的唯一Java类型可能是
List
(也就是说,可能没有通配符可以解析为的有效类型,例如在异构列表的情况下)


也就是说,需要分析真正动态的数据结构是比较少见的。通常任何JSON数据都有一个标准化的结构,因此正确的解决方案是构建一个数据对象(作为Java POJO类)表示该结构,然后将传入数据转换为对象。如果无法在对象中表示数据,则这意味着传入数据不是您的程序准备好处理的数据。在大多数情况下,您应该立即中止,并出现错误,而不是试图混弄您不了解的数据tand(这是“快速失败”原则)。

您需要对
(String)
进行显式强制转换。该强制转换可能会失败(使用
ClassCastException
)在运行时,如果类型不匹配。是的..你是正确的,这样做总是很好的做法,以避免任何CCE我不确定我是否理解你的评论,但强制转换肯定不会避免异常。嗯..请告诉我如何处理未经检查的运行时异常,如CCE?在编译时无法知道是否有gonna是一个例外,另一个选项是在所有可能的位置插入try-catch块。这样做的更好方法是什么。如果您获得的JSON数据的类型与您期望的不同,您希望发生什么?还要注意,您编写的代码应该生成一个
rawtypes
警告,您应该密切关注编译器警告你,正是因为这段代码不是类型安全的。另外:如果你知道JSON对象的类型和结构,那么为什么不使用POJO类进行反序列化呢?这可能会更加类型安全,总体上代码行数更少。我想避免使用POJO类来减少代码。请参阅下面的注释。谢谢定义一个类不需要太多的代码——例如,您展示的示例数据,您可以用五行代码声明一个类。如果此数据表示您将在整个程序中与之交互的实体,您应该已经为其创建了一个专用的数据类型。如果您不创建类来表示您的程序使用的数据,那么你没有有效地使用语言。抓(和吞咽!)
异常
是一种非常糟糕的做法。要么你应该展示如何处理异常情况的正确示例,要么你的代码根本不应该尝试捕获异常。抛出IOException、JsonParseException、JsonMappingException或者它需要处理并需要在方法签名中添加抛出。由你决定。关于编辑:从技术上讲,
getClass()
将返回与对象的运行时类型的擦除相对应的
Class
对象,而不是确切的类型(尽管在实践中这些类型通常是相同的)。特别是对于嵌套的容器类型,如
Map
List
getClass()
不会告诉您有关元素类型的任何有用信息。您将如何执行此操作?另外:通过
(int)
而不是
(Integer)
(然后隐式返回到
Integer
)将调用不必要的取消装箱和装箱转换,这将导致在值实际为
null
时引发
NullPointerException
。如果这是您实际需要的,那么您可能应该使用类似
Objects.requireNonNull()
的内容以明确说明问题。
    String jsonString = "{\"age\":12,\"location\":\"UK\",\"gender\":\"male\"}";

    ObjectMapper mapper = new ObjectMapper();
    try {
        Map map = mapper.readValue(jsonString, Map.class);
        System.out.println(map);
        Integer age = (int)map.get("age");
        System.out.println(age);
        System.out.println(map.get("age").getClass());
    }catch (IOException|NullPointerException e){}
System.out.println(map.get("age").getClass());