eclipse 不应该分配参数“foo”——有什么危害?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3972510/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 15:12:43  来源:igfitidea点击:

The parameter 'foo' should not be assigned -- what's the harm?

javaeclipsewarningscompiler-warnings

提问by Matt McHenry

Compare this method:

比较这个方法:

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

    // lots of complex processing on val
}

... to this method:

...这个方法:

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

    // lots of complex processing on val
}

For the former method, Eclipse emits the warning "The parameter 'val' should not be assigned". Why?

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

To my eye, the former is cleaner. For one thing, it doesn't force me to come up with twogood names for val(coming up with one good one is hard enough).

在我看来,前者更干净。一方面,这并不强迫我想出两个好名字val(想出一个好名字就够难了)。

(Note: Assume there is no field named valin the enclosing class.)

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

回答by andersoj

It doesn't look like anyone's made the curmudgeon's case here.

看起来没有人在这里提出了脾气暴躁的案例。

I would generally not mutate parameters, and in fact I tend to mark my parameters finalin order to explicitly forbid it. A few reasons:

我通常不会改变参数,事实上我倾向于标记我的参数final以明确禁止它。几个原因:

  • Assignment to a parameter could be confused with an attempt to use it as an "output parameter", ref: javapractices.com, and clarity is everything

  • Favor Immutability, and that goes for parameter values as much as anything else. Primitives are just a degenerate case of the same thing, it's (generally) easier to reason about immutable variables. Ref, Effective Java Item 13, or javapractices.com

  • And finally (NPI), Use final liberally, javapractices.com. However ugly it may be in parameter signatures, I believe it tends to identify unexpected errors and it highlights mutable variables, which generally should be the exception. Most mutable variables in most code are there either for laziness or a perception that it has some effect on performance, when judiciously chosen, immutable, and well-named intermediate computations are clearer, easier to read and verify, and can be cleanly optimized for performance with no help from you.

  • 对参数的赋值可能与将其用作“输出参数”的尝试混淆,参考:javapractices.com,清晰就是一切

  • 支持 Immutability,这对参数值和其他任何东西都一样。基元只是同一事物的退化情况,(通常)更容易推理不可变变量。参考、Effective Java Item 13javapractices.com

  • 最后(NPI),自由使用 finaljavapractices.com。不管它在参数签名中可能有多丑陋,我相信它倾向于识别意外错误并突出显示可变变量,这通常应该是例外。大多数代码中的大多数可变变量要么是为了懒惰,要么是因为它对性能有一些影响,当明智地选择、不可变和命名良好的中间计算更清晰、更易于阅读和验证,并且可以干净地优化性能时没有你的帮助。

I can't speak intelligently to your specific case in the abstract, but barring all the other things I might do differently, I'd favor:

我无法抽象地对您的具体案例进行明智的发言,但除非我可能会以不同的方式做所有其他事情,否则我会赞成:

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

or even (assuming you wouldn't cope with a null value in a real method with only one argument, it must be part of something more complex)... Also, in general, methods which accept nullas a parameter should be explicitly documented as doing so, if only to reinforce the assumption that null parameters ought to be the exception. In the second method, you might even make use of the @NonNullannotation.

甚至(假设你不会在只有一个参数的真实方法中处理空值,它必须是更复杂的东西的一部分)......此外,一般来说,接受null作为参数的方法应该明确记录为这样做只是为了加强空参数应该是例外的假设。在第二种方法中,您甚至可以使用@NonNullannotation

/**
  * @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
}

Related questions (and associated argument) on StackOverflow: "Using final modifier whenever applicable in Java...", "final keyword in method parameters", "Do you final-ize local variables and method parameters in Java".

StackOverflow 上的相关问题(和相关参数): “在 Java 中适用时使用 final 修饰符...”“方法参数中的 final 关键字”“您是否在 Java 中最终化局部变量和方法参数”

回答by Nikita Rybak

It's sometimes considered a bad practice to reassign parameters inside method. It, probably, comes from C/C++, where calling doSomething(myVar)can change myVarafter method is completed. But that's not the case for Java.

在方法内部重新分配参数有时被认为是一种不好的做法。它可能来自 C/C++,在方法完成后调用doSomething(myVar)可以改变myVar。但对于 Java 而言,情况并非如此。

IMHO, if you do it as first thing in the method, this is perfectly fine. Everybody reading your code will understand what's going on. It can be confusing if buried deep in the code, though.

恕我直言,如果您将其作为方法中的第一件事,那就完全没问题了。每个阅读你代码的人都会明白发生了什么。但是,如果深埋在代码中可能会令人困惑。

回答by Josh Lee

In my experience, the use of nullas a sentinel for the default parameter is more of an idiom in Python. In Java, you can just overload the method.

根据我的经验,将null用作默认参数的哨兵在 Python 中更像是一种习惯用法。在 Java 中,您可以只重载该方法。

void doStuff() {
    doStuff(DEFAULT_VALUE);
}

void doStuff(final String val) {
    assert (val != null); // or whatever
    ...
}

回答by Ladlestein

There is a compiler preference which dictates whether or not an instance of parameter assignment is ignored, flagged with a warning, or flagged with an error.

有一个编译器首选项,它指示参数分配的实例是否被忽略、标记为警告或标记为错误。

Go to the menu bar - choose Window..Preferences, then In the tree control of the Preferences dialog, select Java..Compiler..Errors/Warnings, then Look in the Code Style section for the "Parameter Assignment" setting.

转到菜单栏 - 选择 Window..Preferences,然后在 Preferences 对话框的树控件中,选择 Java..Compiler..Errors/Warnings,然后在 Code Style 部分中查找“Parameter Assignment”设置。

alt text

替代文字

回答by maerics

I suspect it's a style issue; more of a guideline for programmers than an actual potential problem. Some might find it misleading to dispose of the original parameter value.

我怀疑这是一个风格问题;更多的是程序员的指南,而不是实际的潜在问题。有些人可能会发现处理原始参数值会产生误导。