在 JSON 中表示 null

Representing null in JSON

提问人:pherris 提问时间:1/15/2014 最后编辑:Paulo Mattospherris 更新时间:1/12/2023 访问量:1013605

问:

在 JSON 中返回 null 值的首选方法是什么?对基元有不同的偏好吗?

例如,如果我在服务器上的对象有一个名为“myCount”的整数,但没有值,则该值最正确的 JSON 将是:

{}

{
    "myCount": null
}

{
    "myCount": 0
}

字符串的相同问题 - 如果我在服务器上有一个空字符串“myString”,是最好的 JSON:

{}

{
    "myString": null
}

{
    "myString": ""
}

或(主啊,帮助我)

{
    "myString": "null"
}

我喜欢在JSON中将集合表示为空集合的约定 http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

将表示一个空的 Array:

{
    "myArray": []
}

编辑摘要

“个人偏好”的论点似乎是现实的,但目光短浅,因为作为一个社区,我们将消费越来越多的不同服务/来源。JSON结构的约定将有助于规范化上述服务的消费和重用。就建立标准而言,我建议采用大多数杰克逊公约,但有一些例外:

  • 对象优先于基元。
  • 空集合优先于 null。
  • 没有值的对象表示为 null。
  • 基元返回其值。

如果要返回一个主要为 null 值的 JSON 对象,则可能有一个重构为多个服务的候选项。

{
    "value1": null,
    "value2": null,
    "text1": null,
    "text2": "hello",
    "intValue": 0, //use primitive only if you are absolutely sure the answer is 0
    "myList": [],
    "myEmptyList": null, //NOT BEST PRACTICE - return [] instead
    "boolean1": null, //use primitive only if you are absolutely sure the answer is true/false
    "littleboolean": false
}

上面的 JSON 是从以下 Java 类生成的。

package jackson;    
import java.util.ArrayList;
import java.util.List;    
import com.fasterxml.jackson.databind.ObjectMapper;
    
public class JacksonApp {    
    public static class Data {    
        public Integer value1;    
        public Integer value2;
        public String text1;
        public String text2 = "hello";
        public int intValue;
        public List<Object> myList = new ArrayList<Object>();
        public List<Object> myEmptyList;
        public Boolean boolean1;
        public boolean littleboolean;   
   }
    
   public static void main(String[] args) throws Exception {
       ObjectMapper mapper = new ObjectMapper();
       System.out.println(mapper.writeValueAsString(new Data()));
   }
}

Maven 依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>
json null 杰克逊 gson

评论

7赞 Philipp Reichart 1/15/2014
没有最好的方法。在具体用例中选择最容易为客户端使用的内容。本着返回空集合而不是 的精神,考虑您的客户端是否更适合使用空字符串,或者 -- 包含单词“null”的字符串与有效值无法区分,请不要这样做。nullnull
6赞 John Sheehan 1/15/2014
0 或空字符串很可能与 null 具有不同的含义,null 可能与不存在的属性具有不同的含义。如果要表示 null,请使用 null。这是最明确的。
1赞 Hot Licks 1/15/2014
在 Objective-C 中,有一个定义的类,它有一个单例实例。对该实例的引用等同于 JSON 的 .我猜另一种语言可以做同样的事情。当然,在转换为假定的类之前,必须检查接收对象的类 - 可以说是“空感知”。NSNullnull
2赞 Periata Breatta 10/13/2016
请注意,在 Java 中,拥有“null”列表也不是最佳实践:如果列表预期为空,请将其初始化为空列表。如果需要保持空(例如,因为它将被新列表批量替换,而不是修改以添加值),请将其初始化为空列表(即)。这样做可以避免 null 引用 bug,否则可能会很痛苦。Collections.emptyList()
0赞 Periata Breatta 10/13/2016
@HotLicks - 这之所以可能,是因为 Objective-C 是动态类型的。例如,在Java中,你不能有一个(有用的)类,因为你只能将其值分配给它自己的类型或类型的对象。NullObject

答:

9赞 Alexei Levenkov 1/15/2014 #1

我会为变量的数据类型选择“默认”(对于字符串/对象,对于数字),但确实会检查将消耗对象预期的代码。别忘了,/default 和 “not present” 之间有时是有区别的。null0null

查看 null 对象模式 - 有时最好传递一些特殊对象而不是(即 array,而不是数组或字符串)。null[]null""

2赞 Wayne 1/15/2014 #2

这是个人和情境的选择。需要记住的重要一点是,空字符串和数字零在概念上与 不同。null

对于 a,您可能总是想要一些有效的数字(除非 未知或未定义),但对于字符串,谁知道呢?空字符串可能在应用程序中表示某些含义。或者也许没有。这由你来决定。countcount

17赞 marcoseu 1/15/2014 #3

我会用它来表明该特定键没有值。例如,用于表示“您家中连接到互联网的设备数量”未知。nullnull

另一方面,如果该特定密钥不适用,请使用。例如,即使向没有汽车的人询问“具有有效互联网连接的汽车数量”问题,也不应显示计数。{}null

我会避免默认任何值,除非该默认值有意义。虽然你可以决定使用来表示没有价值,但肯定不要这样做。null"null"

549赞 brandonscript 1/15/2014 #4

让我们评估一下每个的解析:

http://jsfiddle.net/brandonscript/Y2dGv/

var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';

console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}

tl;DR在这里:

json2 变量中的片段是 JSON 规范指示的表示方式。但与往常一样,这取决于你在做什么——有时“正确”的方法并不总是适合你的情况。运用你的判断力,做出明智的决定。null


JSON1 {}

这将返回一个空对象。那里没有数据,它只会告诉你,你要找的任何键(无论是它还是其他东西)都是类型。myCountundefined


JSON2 {“myCount”: null}

在这种情况下,实际上是定义的,尽管它的值是 。这与“not and not”不同,如果您正在测试一个条件或另一个条件,这可能会成功,而 JSON1 会失败。myCountnullundefinednull

这是根据 JSON 规范表示的最终方法。null


JSON3 {“myCount”: 0}

在本例中,myCount 为 0。这与 不同,也不等同于 。如果您的条件语句计算 ,那么这可能是值得的。此外,如果您根据此处的值运行计算,则 0 可能很有用。但是,如果您尝试测试,这实际上根本行不通。nullfalsemyCount > 0null


JSON4 {“myString”: “”}

在本例中,你得到一个空字符串。同样,与 JSON2 一样,它是定义的,但它是空的。您可以测试,但不能测试 或 。if (obj.myString == "")nullundefined


JSON5 {“myString”: “空”}

这可能会给您带来麻烦,因为您将字符串值设置为 null;然而,在这种情况下,它不是.obj.myString == "null"== null


JSON6 {“myArray”: []}

这将告诉您您的数组存在,但它是空的。如果您尝试对 执行计数或评估,这将非常有用。例如,假设您想评估用户发布的照片数量 - 您可以这样做,它会返回:已定义,但没有发布照片。myArraymyArraymyArray.length0

评论

1赞 Neil 12/20/2017
非常感谢,非常有帮助。只是一个很小的侧节点;当 Play Json (scala) 序列化 Option[String] = None 时,结果是JSON1{}
2赞 jaquinocode 2/26/2022
没有选项吗?是否可以为空对象设置值?{"myObject": {}}
1赞 brandonscript 2/26/2022
当然,继续。它的含义与 null 不同。
267赞 Nicholas Carey 1/15/2014 #5

null不为零。它本身不是一个值:它是变量域之外的值,表示缺失或未知数据。

只有一种方法可以在 JSON 中表示。根据规范(RFC 4627json.org):null

2.1.  Values

A JSON value MUST be an object, array, number, or string, or one of
the following three literal names:

  false null true

enter image description here

评论

11赞 Richard A Quadling 4/16/2015
真是太可惜了,null 必须存在。4个字符一无是处。如果只是完全排除该值,那就太好了。json = '{"myValue":}';
176赞 Scott Smith 5/27/2015
@Richard A Quadling - 我是 Hal Abelson 的追随者,“程序必须为人们阅读而编写,并且只是偶然为机器执行”。我更喜欢“null”这个词,它证实了程序员的意图,而不仅仅是一个意外遗漏的问题。
20赞 Scott Smith 5/24/2016
@Dave May:“JSON 值不是程序”——我的观点是关于以一种明确的方式传达意图。是的,它需要额外花费四个字符,对于某些应用程序,差异可能很大。然而,在许多情况下,让错误看起来错误的好处远远超过小优化的好处。
13赞 Sophivorus 7/7/2016
@Dave 此外,根据 json.org 的说法,JSON“对人类来说很容易读写”。
21赞 PhoneixS 4/11/2018
另请注意,如果您遇到 4 个 ASCII 字符的问题,JSON 不是最佳方法,请查看二进制 JSON 或更好的纯二进制格式。
47赞 dnozay 12/19/2015 #6

只有一种表示方式;也就是说,.nullnull

console.log(null === null);   // true
console.log(null === true);   // false
console.log(null === false);  // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === "");     // false
console.log(null === []);     // false
console.log(null === 0);      // false

也就是说;如果任何使用您的 JSON 表示的客户端使用运算符;这对他们来说可能是一个问题。===

无值

如果要传达一个属性没有值的对象:myCount

{ "myCount": null }

无属性/缺少属性

如果你要传达你有一个没有属性的对象,该怎么办?

{}

客户端代码将尝试访问并获取;它不在那里。myCountundefined

空集合

如果您要传达您的对象具有空列表的属性,该怎么办:myCount

{ "myCount": [] }

评论

1赞 Mladen B. 2/6/2018
+1 比较的好例子,但区分 javascript 和 json 会很有帮助,这意味着 javascript 中 null 的表示不必与 JSON 匹配(尽管确实如此)。
4赞 iggie 8/11/2018 #7

根据 JSON 规范,最外层的容器不必是字典(或“对象”),如上面大多数注释中所暗示的那样。它也可以是列表或裸值(即字符串、数字、布尔值或 null)。如果要在 JSON 中表示 null 值,则整个 JSON 字符串(不包括包含 JSON 字符串的引号)只是 .没有大括号,没有括号,没有引号。您可以指定一个字典,其中包含一个具有 null 值 () 的键,或者一个具有 null 值 () 的列表,但这些本身不是 null 值 - 它们是正确的字典和列表。同样,空字典 () 或空列表 () 也很好,但也不是 null。null{"key1":null}[null]{}[]

在 Python 中:

>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None

评论

0赞 yoyoyoyosef 6/2/2020
请注意,链接的 JSON 规范页面右侧边栏上的 McKeeman 表单语法验证了 bare 构成有效 JSON 的断言。那里的正文和插图是模棱两可的,如果有的话,似乎只有对象和数组在根上是有效的。null
1赞 Jesse 5/15/2022 #8

“null”最适合实际使用

FWIW,以PHP为例,PHP将空集解释为PHP制作的条目...

// This loop will iterate one item with the value 'the car'
$empty_json = '["the car"]';
$some_json_array = json_decode($empty_json);

foreach ($some_json_array as $i) {
  echo "PHP sees one item";
}

输出:PHP sees the car

// This loop will iterate one item, but with no values
$empty_json = '[""]';
$some_json_array = json_decode($empty_json);

foreach ($some_json_array as $i) {
  echo "PHP sees: $i";
}

输出:PHP sees

// This loop will iterate nothing because PHP's `json_decode()` function knew it was `null`
$empty_json = 'null';
$some_json_array = json_decode($empty_json);

foreach ($some_json_array as $i) {
  echo "PHP sees one item";
}

输出:(nothing,不会循环)foreach

评论

0赞 Jesse 5/15/2022
此问题不限于 或 ,尽管它在问题中有一个 Java 示例,在另一个答案中有一个 Python 示例。这个答案显示了PHP中的一些内容,以完善答案所涵盖的领域。javaphython