在使用 Jackson 时,我应该使用包装器还是原始类型作为字段
Should I use a wrapper or primitive type as field while using Jackson
我正在使用 Jackson
JSON
解析器。我有一个简单的数据传输对象,应该通过 REST
服务返回。
public class PersonDto {
private String name;
private Integer age; // int?
public PersonDto(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
}
在这种情况下,我是否应该支持包装器 类 而不是原始类型作为字段?除了 wrapper 可以为 nullable 之外,这些方法中哪种方法更有优势?
包装器class:java.lang.Integer
优点:
- 允许
null
值,因此给用户留下空白/未指定字段的机会
当值在 -128 到 127 之间时速度很快,因为它使用其内部缓存而不是创建新对象
Integer::valueOf
用于解析 String
的
缺点:
不可变:如果您必须重置该值(例如:因为它超出了某个范围),您将不得不重新创建一个全新的 Integer
实例。
计算性能较慢
java.lang.Integer
是对实例的引用。每次计算都会重新创建一个全新的对象
原始类型:int
优点:
可变(只要非final
,并且提供setter
):轻松允许:this.age = age > MAX_AGE ? blabla : age;
基本类型计算速度更快
Integer::parseInt
用于解析 String
的
缺点:
- 非selected 值将自动设置为 0;这可能会混淆用户是否 selected 0 作为值,或者没有 select 任何东西
似乎 java.lang.Integer
的唯一优势是 blank
/ null
值。
此外,在需要包装器的情况下,例如:
List<Integer> myList;
您可以直接添加一个未装箱的值 myList.add(2);
,编译器会将其解释为 myList.add(Integer.valueOf(2));
我发现在 DTO 中使用包装器很有用。使用 Jackson,对于 nullable fields,您可以在 DTO 对象之上设置 @JsonInclude(JsonInclude.Include.NON_NULL) 并减少数据数量通过网络发送(结果 JSON 中不会出现空字段),从而解决值为 0 或不存在时的歧义,告诉前端不存在节点,因此没有 processing/displaying 数据需要。
对于不可为 null 的数字数据,primitive 效果很好。
此外,对于算术计算中不应在前端使用的浮点数据,可以使用在服务器端进行舍入的 String。我在 REST API 中多次看到这种技术。
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
System.out.println(df.format(d));
我正在使用 Jackson
JSON
解析器。我有一个简单的数据传输对象,应该通过 REST
服务返回。
public class PersonDto {
private String name;
private Integer age; // int?
public PersonDto(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
}
在这种情况下,我是否应该支持包装器 类 而不是原始类型作为字段?除了 wrapper 可以为 nullable 之外,这些方法中哪种方法更有优势?
包装器class:java.lang.Integer
优点:
- 允许
null
值,因此给用户留下空白/未指定字段的机会 当值在 -128 到 127 之间时速度很快,因为它使用其内部缓存而不是创建新对象
Integer::valueOf
用于解析String
的
缺点:
不可变:如果您必须重置该值(例如:因为它超出了某个范围),您将不得不重新创建一个全新的
Integer
实例。计算性能较慢
java.lang.Integer
是对实例的引用。每次计算都会重新创建一个全新的对象
原始类型:int
优点:
可变(只要非
final
,并且提供setter
):轻松允许:this.age = age > MAX_AGE ? blabla : age;
基本类型计算速度更快
Integer::parseInt
用于解析String
的
缺点:
- 非selected 值将自动设置为 0;这可能会混淆用户是否 selected 0 作为值,或者没有 select 任何东西
似乎 java.lang.Integer
的唯一优势是 blank
/ null
值。
此外,在需要包装器的情况下,例如:
List<Integer> myList;
您可以直接添加一个未装箱的值 myList.add(2);
,编译器会将其解释为 myList.add(Integer.valueOf(2));
我发现在 DTO 中使用包装器很有用。使用 Jackson,对于 nullable fields,您可以在 DTO 对象之上设置 @JsonInclude(JsonInclude.Include.NON_NULL) 并减少数据数量通过网络发送(结果 JSON 中不会出现空字段),从而解决值为 0 或不存在时的歧义,告诉前端不存在节点,因此没有 processing/displaying 数据需要。 对于不可为 null 的数字数据,primitive 效果很好。 此外,对于算术计算中不应在前端使用的浮点数据,可以使用在服务器端进行舍入的 String。我在 REST API 中多次看到这种技术。
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
System.out.println(df.format(d));