当前位置: 首页 > 面试题库 >

不应分配参数“ foo”,这有什么害处?

谷奕
2023-03-14
问题内容

比较这种方法:

void doStuff(String val) {
    if (val == null) {
        val = DEFAULT_VALUE;
    }

    // lots of complex processing on val
}

…对此方法:

void doStuff(String origVal) {
    String val = origVal;
    if (val == null) {
        val = DEFAULT_VALUE;
    }

    // lots of complex processing on val
}

对于前一种方法,Eclipse发出警告“不应分配参数’val’”。为什么?

在我看来,前者更清洁。一方面,这并不会迫使我想出 两个 好名字val(想出一个好名字已经够难了)。

(注意:假定val在封闭的类中没有命名字段。)


问题答案:

看起来好像没有人在这里做过举动。

我通常不会更改参数,实际上,我倾向于标记我的参数final以明确禁止使用它。原因如下:

  • 分配参数可能会 与尝试将其用作“输出参数” 混淆,请参见:javapractices.com,清晰度就是一切

  • 支持不可变性 ,这和其他任何参数一样适用于参数值。基元只是同一事物的简并案例,(通常)更容易推断出不可变的变量。参考,有效的Java项目13或javapractices.com

  • 最后(NPI), 自由使用final ,javapractices.com。无论它在参数签名中是多么丑陋,我相信它都倾向于识别意外错误,并且突出显示了可变变量,通常应该是例外。在大多数代码中,大多数可变变量都是出于懒惰,或者是认为它对性能有一定影响,因此,如果明智地选择,不变和命名良好的中间计算,则更清晰,更易于阅读和验证,并且可以针对性能进行干净优化没有您的帮助。

我不能抽象地对您的特定情况进行明智地讲,但是除非我可能做不同的其他所有事情,否则我赞成:

void doStuff(final String origVal)
{
    final String valOrDefault = (origVal == null) ? DEFAULT_VALUE : origVal;
    //lots of complex processing on valOrDefault 
}

甚至(假设在一个只有一个参数的实数方法中您将无法处理空值,它必须是更复杂的东西的一部分)…而且,通常,接受null为参数的方法应明确记录为:这样做,仅仅是为了加强这样的假设,即空参数应该是例外。在第二种方法中,您甚至可以使用@NonNull注解。

/**
  * @param origVal string giving value, possibly null, in which case DEFAULT_VALUE is assigned
  */
void doStuff(final String origVal, ... )
{
    final String valOrDefault = (origVal == null) ? DEFAULT_VALUE : origVal; 
    // similar mucking about to make all the parameters behave, separate from
    // actually operating on them...
    ...
    reallyDoStuff(valOrDefault,...);
}

private void reallyDoStuff(final String value, ...)
{
   assert (value != null);
   // do your complex processing
}


 类似资料:
  • 问题内容: 在Swift中,您可以使用if let可选绑定将可选内容解包为具有相同名称的常量或变量: 对于语句中的所有内容,可选项都被包装为常规int。 同样,我可以使用保护语句来达到类似的效果 但是,我不能使用这样的代码: 为什么不? 在保护语句中,如果保护语句的条件失败,则执行else子句,然后退出当前作用域。如果条件成功,则将从保护语句的右括号到当前作用域的结尾创建一个新的变量/常量。 为什

  • 问题内容: 为什么是选择?如果添加了想要的新列,这是否意味着更少的代码更改? 我知道这在某些数据库上是性能问题,但是如果您真的想要每列,该怎么办? 问题答案: 确实有三个主要原因: 将数据转移到消费者方面效率低下。 当您选择SELECT *时,通常从数据库中检索到的列数超出了应用程序实际需要运行的列数。这将导致更多数据从数据库服务器移至客户端,从而减慢访问速度并增加计算机上的负载,并花费更多时间在

  • 问题内容: 我看到其他地方说: 等于 我测试了一下,他们确实做了同样的事情。但为什么?到底是什么? 问题答案: AND和OR运算符都可以捷径。 因此,仅在第一个表达式为true时才尝试第二个表达式(更确切地说,是类似事实的表达式)。第二个操作确实起作用(无论其内容如何)的事实无关紧要,因为除非第一个表达式的计算结果为真,否则它不会执行。如果是事实,则将执行它以尝试第二次测试。 相反,如果语句中的第

  • 以上是目前我的CNN的架构。然而,它说它有1.8m可训练的参数。为什么会这样?我以为第一层给出了(32*4=128个参数),但是我如何找到模型的其余部分有多少个参数? 我的理解是,CNN架构应该只依赖于过滤和最大池,因为它们是共享权重。为什么我有这么多参数?我应该如何着手减少这个数字? 我不是问如何使用“汇总”找到参数的数量。我是问为什么我的模型有这么多参数,以及我如何减少这个数字。我不直观地理解

  • 问题内容: 在查看在线源代码时,我在几个源文件的顶部遇到了这个问题。 但是我不知道该怎么办。 我知道等于,我认为表示类似“如果它已经存在,请使用其值,否则请使用新对象。 为什么我会在源文件的顶部看到它? 问题答案: 您对的意图的猜测非常接近。 当在文件顶部看到该特定模式时,该模式用于创建 名称空间 (即命名对象),在该 命名空间 下可以创建函数和变量,而不会过度污染全局对象。 究其原因 ,为什么

  • 问题内容: 我想知道为什么它是Java不允许超负荷使用,虽然他们都以不同的方式使用? 使用方式如下: 而另一种形式: 使用方式如下: 这背后有什么原因吗? 问题答案: 这个15.12.2.5选择最具体的方法对此进行了讨论,但是它相当复杂。例如,在Foo(数字…整数)和Foo(整数…整数)之间进行选择 为了向后兼容,这些实际上是同一件事。 例如,您可以将main()定义为 一种使它们与众不同的方法是