我应该预先初始化在多个分支中被覆盖的变量吗?

Mic*_*u93 19 java string

有一种方法:

private String myMethod(String gender)
{
    String newString = "";
    if(gender.equals("a"))
        newString = internal.getValue();
    else
        newString = external.getValue();

    return newString;
}
Run Code Online (Sandbox Code Playgroud)

我重构了所有内容,但有一个小的更改: String newString;而不是:String newString = "";

这样重构可以改善代码吗?我知道那Stringnull当我们不初始化它的时候,但是在这个例子中,它总是有a if或from的值else。这个重构会改变什么吗?

Rog*_*gue 24

要回答直接的问题:这里不需要最初分配值;代码执行的所有分支都将平移以提供newString一个值。因此,您根本不需要初始化它。否则,我将初始化为“默认”值。

代替两个返回值或一个分支语句来分配变量,我只返回一个三元数:

private String myMethod(String gender) {
    return gender.equals("a")
            ? internal.getValue()
            : external.getValue();
}
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,条件运算符并不是 if/else 的语义替代。这里并不重要,但是,比如说,`Number foo(boolean c) { if (c) return Integer.valueOf(0); 否则返回 Double.valueOf(0); }` 与 `return c 不同吗?Integer.valueOf(0) : Double.valueOf(0);`,因为后者总是导致“Double”。 (2认同)

And*_*ner 19

初始化String还是将其保留为null更好?

您的前提是有缺陷的:不初始化String并不意味着它的值为null。

在分配局部变量之前,不允许使用该变量,以避免您意外使用您不希望使用的值。因此,该值不是“ null”,而是未定义(*)。

这称为确定分配检查,用于防止某些类型的错误。如果为变量提供了不需要的值,则将禁用此检查,因此容易受到编译器试图保护您免受其攻击的错误的影响。

例如,如果代码如下所示:

private String myMethod(String gender)
{
    String newString = "";
    if(gender.equals("a"))
        newString = internal.getValue();
    else if (gender.equals("b");
        newString = external.getValue();
    // Oops! meant to check if gender.equals("c")

    return newString;
}
Run Code Online (Sandbox Code Playgroud)

您可能有一个错误,因为有一个尚未检查的遗漏案例。

如果您已显式分配null给变量,那么您将遇到很多相同的问题。但是现在您的方法将返回null,因此可能导致调用代码中出现NPE。

如果您省略了= "",则编译器将newString在返回时停止使用。

(分配和重新分配变量也意味着该变量实际上不是最终变量,因此您将无法在lambda或匿名类中使用它)。


(*)仅适用于局部变量和final成员/静态变量。如果类成员不是最终成员,则不必在使用前对其进行明确分配,这是对错误的丰富缝隙,并且是使类成员尽可能成为最终成员的充分理由。并且,从技术上讲,final成员首先被初始化为其类型的默认值,因此您实际上可以像null在它们被初始化之前一样读取它们。


Eri*_*son 10

String如果存在使用初始值的情况,最好只初始化一个(或其他任何东西)。

在您的情况下,您已分配newString给一个字符串文字,该文字没有任何作用,只是会使读者感到困惑。

显然,性能和功能不会以任何相关方式改变。