我读了Why should Java 8's Optional not be used in arguments。但是@PostMapping("/signup")
public @ResponseBody
RealityKeeper createUser(@RequestBody SignupRequest signupRequest) {
System.out.println("SignupRequest: " + signupRequest);
String password = signupRequest.getPassword();
String username = signupRequest.getUsername();
String encoded = passwordEncoder.encode(password);
RealityKeeper realityKeeper = new RealityKeeper(username, encoded);
return repository.save(realityKeeper);
}
呢,有反对使用它们作为输入参数的论点吗?
据我正确理解,它们不能为空,而是为空(输入参数中针对@Test
public void createUser() throws Exception {
SignupRequest signupRequest = new SignupRequest("foo", "bar");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String requestJson=ow.writeValueAsString(signupRequest);
mockMvc.perform(post("/api/signup")
.contentType(MediaType.APPLICATION_JSON)
.content(requestJson))
.andExpect(MockMvcResultMatchers.status().isOk());
}
的主要参数),但是可能还有其他礁石吗?我应该使用Optional(Int|Long|Double)
而不是Optional<X>
的值来使用OptionalInt
或Integer
吗?
答案 0 :(得分:10)
不使用Optionals作为方法参数的想法不仅针对Optional<T>
,而且还适用于所有类型的Optionals。
当你说:
据我正确理解,它们不能为空,但可以为null (输入参数中针对
Optional<X>
的主要自变量参数)
首先,我们要弄清术语的正确性,当Optional<X>
包含非空引用时,我们说它是存在,否则我们说{ {1}}是空或缺席。您不应该说Optional<X>
包含 null 。
所有Optional都可以为空,无论它是Optional<X>
类型还是原始类型的对象的容器。
例如,如果您浏览OptionalInt类文档,它会显示:
可能包含也可能不包含int值的容器对象。如果一个 值存在,isPresent()将返回true,getAsInt()将 返回值。
强调我的。
当Optional不包含int值时,则为空的Optional。
是否应该将OptionalInt或Integer与null而不是null值一起使用?
关于使用T
或OptionalInt
的确取决于您的使用
案件。
Integer
的容器和
它们是描述性的原始类型,可让它们应用不同的
提取值(如果存在或执行某些操作)的操作类型
否则,如果没有。T
字段分配值 null 。Integer
作为返回类型的方法来返回null
。Integer
字段(有争议的字段)永远不要置为OptionalInt
,因为这样一来就会破坏使用Optional的全部目的。null
的方法返回null
,因为它违背了使用Optional的全部目的。等等。
此外,有些人实际上只是因为缺少OptionalInt
,map
和flatMap
方法而劝阻原始Optional的使用。
本质上,没有规则总是使用Optionals或vera,而是选择最适合您需求的API。
答案 1 :(得分:3)
因此,有3件事需要考虑,将OptionalInt
,Integer
或int
传递给方法(或在此类的类中具有属性)。
通常传递Integer
并不是最好的主意,因为您需要检查null
。实际上,有些人希望这样做,主要是因为Boolean
可以表示3个状态-unknown/true/false
-我仍然不喜欢它(enum
更适合这种情况)。
因此在语义上将null
传递给接受Integer
的方法可能意味着-我不希望出现该值。但是,提供这种方法的代码应负责处理此问题。更好的方法是让重载方法不要将其本身作为输入-因此使IMO清楚,此参数不是强制性的。
好,通过int
更好吗?是的,有点。想一想ORM(休眠);在某些情况下,某个属性可能是int
或Integer
-在这种情况下,我赞成Integer
;主要是因为int
具有默认值或zero
-并且我希望代码以NullPointer
失败而不是保持陈旧的值:零可能是一个完全有效的商业价值,但是如果我们不是要把它表示为zero
吗?当然,这意味着数据库和服务层需要适当的验证,等等-我不再赘述。
那如何将OptionalInt
传递给以前接受Integer
的方法呢?您将仍然需要检查它们是否存在(null
?),仍然需要检查它是否为空并采取相应步骤。这通常意味着您需要根据该参数使用不同的代码路径-在这种情况下,必须传递一些更具描述性的内容。您仍然可以这样做,但是如果及时需要其他条件怎么办? OptionalInt
无法解决这个问题,因此需要进行重大的重构。
但是Optional作为返回类型很棒。如果某个方法返回Integer
,您是否检查了它实际上为空的次数?另一方面,如果方法返回OptionalInt
,则您必须考虑以防万一,该方法将丢失,因为否则您将无法检索其值:除非isPresent?
或任何其他方法其他方法,例如orElse/orElseGet
等