代码之家  ›  专栏  ›  技术社区  ›  Michu93

初始化字符串还是将其保留为空更好?

  •  1
  • Michu93  · 技术社区  · 7 年前

    有一种方法:

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

    我重构了所有的东西,但是有一个小小的改变: String newString; 而不是: String newString = "";

    这个重构是否改进了代码?我知道 String null 当我们不初始化它时,但是在这个例子中,它总是有一个值a from if else . 这个重构改变了什么吗?

    5 回复  |  直到 7 年前
        1
  •  10
  •   John Kugelman Michael Hodel    7 年前

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

    与两个返回或一个分支语句分配变量不同,我只返回一个三值:

    private String myMethod(String gender) {
        return gender.equals("a")
                ? internal.getValue()
                : external.getValue();
    }
    
        2
  •  6
  •   Eric Wilson    7 年前

    最好只初始化 String (或其他)如果有使用初始值的场景。

    在你的情况下,你已经分配 newString 一个字符串文字,除了迷惑读者之外没有任何作用。

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

        3
  •  6
  •   Andy Turner    7 年前

    初始化字符串还是将其保留为空更好?

    你的前提是有缺陷的:不初始化字符串并不意味着它的值为空。

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

    这叫做 definite assignment checking ,是否可以防止某些类型的错误。如果给变量一个不需要的值,则禁用此检查,并且编译器试图保护您不受错误的影响。

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

    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;
    }
    

    你可能有一个bug,因为有一个丢失的案例你还没有检查。

    如果你忽略了 = "" ,编译器将停止使用 newString 作为回报。

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


    (*)这仅适用于局部变量,以及 final 成员/静态变量。如果类成员不是final,则在使用之前不必明确地分配它们,这是bug的丰富接缝,也是尽可能使类成员成为final的一个很好的理由。而且,严格地说, 最终的 成员首先初始化为其类型的默认值,因此实际上可以将其读取为 null 在初始化之前。

        4
  •  2
  •   Thorbjørn Ravn Andersen    7 年前

    我采用的最短形式没有terniary运算符(我认为这会降低可读性):

    private String myMethod(String gender)
    {
        if(gender.equals("a"))
            return internal.getValue();
        return external.getValue();
    }
    

    我可能会有一个完整的 if {...} else {...} 像我自己代码中的其他答案一样构造。

        5
  •  1
  •   Thorbjørn Ravn Andersen    7 年前

    在您的情况下(如果有其他条件),不需要初始化 String ,你可以简单地说 String newString; 这是可以的,因为无论哪种方式,最后都会有一个不同的值。

    private String myMethod(String gender)
    {
        String newString;
    
        if(gender.equals("a"))
            newString = internal.getValue();
        else
            newString = external.getValue();
    
        // Missing return statement.
    }
    

    另外,我看到您有一个返回字符串的函数。假设 newString 变量是您将返回的内容,而不是创建字符串变量,您可以在以下条件下简单地返回字符串:

    private String myMethod(String gender)
    {
        if(gender.equals("a"))
            return internal.getValue();
        else
            return external.getValue();
    }
    
        6
  •  0
  •   Kirill    7 年前

    你可以做这个绳子 final 保持未分配以确保 if 分支分配值:

    final String result;
    if (condition1) {
        result = "one";
    } else if (condition2) {
        result = "two";
    } else {
        result = "other";
    }
    return result;
    

    使用这种方法编译器将检查 result 变量在每个分支中分配一次。如果您再添加一个条件分支,或者如果您试图错误地覆盖变量,则可能会有帮助—编译器将失败并显示错误。

        7
  •  0
  •   Andreas Radauer    7 年前

    我的学校是对的,这可以通过十年的接线员来完成。 此外,我认为尽可能多地防止nullpoiterexeption是非常重要的。 如果性别是空的呢?空指针异常 我会把“A”和性别改成这样:

        private String myMethod(String gender) {
            return "a".equals(gender)
                ? internal.getValue()
                : external.getValue();
        }