OptionalInt作为输入参数

时间:2018-07-30 23:30:34

标签: java java-8 optional

我读了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>的值来使用OptionalIntInteger吗?

2 个答案:

答案 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值一起使用?

关于使用TOptionalInt的确取决于您的使用    案件。

  • 与类型为Integer的容器和 它们是描述性的原始类型,可让它们应用不同的 提取值(如果存在或执行某些操作)的操作类型 否则,如果没有。
  • 可以为任何T字段分配值 null
  • 一个人可以用任何以Integer作为返回类型的方法来返回null
  • Integer字段(有争议的字段)永远不要置为OptionalInt,因为这样一来就会破坏使用Optional的全部目的。
  • 一个人永远不要再以任何一种返回类型为null的方法返回null,因为它违背了使用Optional的全部目的。

等等。

此外,有些人实际上只是因为缺少OptionalIntmapflatMap方法而劝阻原始Optional的使用。

本质上,没有规则总是使用Optionals或vera,而是选择最适合您需求的API。

答案 1 :(得分:3)

因此,有3件事需要考虑,将OptionalIntIntegerint传递给方法(或在此类的类中具有属性)。

通常传递Integer并不是最好的主意,因为您需要检查null。实际上,有些人希望这样做,主要是因为Boolean可以表示3个状态-unknown/true/false-我仍然不喜欢它(enum更适合这种情况)。

因此在语义上将null传递给接受Integer的方法可能意味着-我不希望出现该值。但是,提供这种方法的代码应负责处理此问题。更好的方法是让重载方法不要将其本身作为输入-因此使IMO清楚,此参数不是强制性的。

好,通过int更好吗?是的,有点。想一想ORM(休眠);在某些情况下,某个属性可能是intInteger-在这种情况下,我赞成Integer;主要是因为int具有默认值或zero-并且我希望代码以NullPointer失败而不是保持陈旧的值:零可能是一个完全有效的商业价值,但是如果我们不是要把它表示为zero吗?当然,这意味着数据库和服务层需要适当的验证,等等-我不再赘述。

那如何将OptionalInt传递给以前接受Integer的方法呢?您将仍然需要检查它们是否存在(null?),仍然需要检查它是否为空并采取相应步骤。这通常意味着您需要根据该参数使用不同的代码路径-在这种情况下,必须传递一些更具描述性的内容。您仍然可以这样做,但是如果及时需要其他条件怎么办? OptionalInt无法解决这个问题,因此需要进行重大的重构。

但是Optional作为返回类型很棒。如果某个方法返回Integer,您是否检查了它实际上为空的次数?另一方面,如果方法返回OptionalInt,则您必须考虑以防万一,该方法将丢失,因为否则您将无法检索其值:除非isPresent?或任何其他方法其他方法,例如orElse/orElseGet