【问题标题】:Problem with scoped local variables and conditionals作用域局部变量和条件的问题
【发布时间】:2009-06-24 03:36:30
【问题描述】:

我正在尝试构造返回布尔值的方法:

public boolean isStringValid(String s){
    boolean isValid;
    String temp = null;     
    // only combinations of 'A','B','C' are allowed
    for (int i = 0; i < s.length(); i++)
    {
        temp = s.substring(i, i+1);
        if (temp.equals("A")|temp.equals("B")|temp.equals("C")){
            isValid= true;
        }else{
            isValid= false;
        }
    }   
    return isValid;
}

但我收到一个编译器错误,提示“局部变量 isValid 可能尚未初始化”。

我要做的是获取一个字符串并检查它的每个字母,如果在字符串中找到除 A、B 或 C 之外的任何字母,isStringValid 方法应该返回 false。只有在检查每个字母并发现是A,B或C之后,该方法才能返回true。

我想我无法确定局部变量的范围。该方法从 if/else 块中返回的适当方式是什么?如果这不可能,你会推荐什么是最好的设计方法?

感谢您提前 最诚挚的问候

【问题讨论】:

  • IMO-s 是一个糟糕的变量名,如果它在原始代码中,请更改
  • 作为建议,当对常量使用 equals 时,请尝试在常量对象上调用它:例如:"A".equals(temp);这样,如果 temp 为 null,您将不会得到 NullPointerException,而 equals 将产生 false。
  • @Tom:由于temp变量来自substring方法,这里不能为null。在其他情况下,是的,这样做很有用。

标签: java variables core local


【解决方案1】:

如果你得到一个空字符串作为参数会发生什么?

编译器需要确保你总是返回一些东西。用 false 初始化你的 isValid 变量,这样如果方法得到一个空字符串,它只会返回 默认值

boolean isValid = false;

在 Java 中,您不能返回一个可能未初始化的变量,只要确保在所有可能的流程中该变量设置为任何值。

更新:这将解决你的问题,但我建议你看看下面的答案,因为你的方法的逻辑不正确

【讨论】:

  • 最好指出这仅与局部变量有关。你可以声明而不初始化实例变量,当你的代码尝试使用它们时编译器不会抱怨。
【解决方案2】:

也许 for 实际上可能不会循环。所以 isValid 没有设置。

【讨论】:

    【解决方案3】:

    方法错误(除了编译器错误,Victor 解释过)。如果最后一个字母是 C 而其他都是 D 它将返回 true。此外,您应该使用 char,并且您需要两个竖线 (||) 来表示逻辑或。试试:

    public boolean isStringValid(String s){             
                // only combinations of 'A','B','C' are allowed
                for (int i = 0; i < s.length(); i++)
                {
                        char tempChar = s.charAt(i);
                        if (!(tempChar == 'A' 
                           || tempChar == 'B' 
                           || tempChar == 'C'))
                            return false;
                }       
                return true;
    }
    

    如果您想为空字符串返回 false,请从头开始:

    if(s.length() == 0)
      return false;
    

    【讨论】:

    • char 不是对象,你怎么调用 equals 呢?
    • 你是对的,汤姆。这就是我在 bsh 中测试的结果。现已修复。
    【解决方案4】:

    我同意您应该初始化 isValid 布尔变量的答案。

    但是,您可以使用regular expression 做您想做的事

    /*
    * returns false if s contains a character different from 'a' 'b' or 'c' 
    */
    public boolean isStringValid(String s){
         return !Pattern.matches("($^|[^abc]+)",s);
    }
    

    [abc] 表示您正在检查 s 是否包含 'a'、'b' 或 'c' 字符

    [^abc] 表示您正在检查 s 是否包含不属于 'a'、'b' 或 'c' 的字符。

    [^abc]+ 表示您正在检查 s 是否包含 至少一个 不是 'a'、'b' 或 'c' 的字符。

    $^ 表示空字符串

    【讨论】:

    • 事实上,您不需要“+”,因为您只是在测试模式是否匹配(这已经暗示了“一次或多次”)
    • @Tom:错误的正则表达式。 “[^abc]+”表示一个或多个字符的序列,不是“a”、“b”或“c”。由于您使用的是matches(),因此整个文本必须与正则表达式匹配。尝试使用“axa”:尽管它“包含至少一个不是'a','b'或'c'的字符”,但它返回false。正确:返回 Pattern.matches("[ABC]*", s); // 只要字符串不包含任何不是“A”、“B”或“C”的字符,则为真
    • 谢谢汤姆和卡罗尔。然而 Pattern.matches("[ABC]*", s);为空字符串返回 true。有没有办法让正则表达式模式包含这个?即如果字符串为空,则返回 false。我尝试了所有建议的解决方案并且它们有效。我喜欢这个,因为它简洁。再次感谢
    • @denchr> 试试 Pattern.matches("[^abc]+",s)。 '*' 表示 0 或更多。
    【解决方案5】:

    变量isValid 是一个局部变量。在 Java 语言规范中:

    一个局部变量(§14.4, §14.13)必须 在它之前被显式地赋予一个值 被使用,通过任一初始化 (§14.4)或转让(§15.26),在 可以通过验证的方式 编译器使用明确的规则 任务。

    参见 Java 语言规范中的 4.5.5 变量的初始值部分:

    http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html

    将变量初始化为 false 以开始,然后仅在方法的正确部分将其设置为 true,即此处:

    if (temp.equals("A")|temp.equals("B")|temp.equals("C")){
       isValid = true;
    }
    

    去掉else语句,让方法正常返回。

    【讨论】:

      【解决方案6】:

      请注意,您的循环只会根据字符串中的最后一个字符返回 true 或 false。你想要做的是类似的事情

      public boolean isStringValid(String s) {
        for (char c : s.toCharArray()) {
          if (!('A' == c || 'B' == c || 'C' == c)) { 
            return false;
          }
        }       
        return true;
      }
      

      【讨论】:

        猜你喜欢
        • 2022-11-16
        • 1970-01-01
        • 2017-07-21
        • 2012-07-09
        • 1970-01-01
        • 2021-03-15
        • 2011-08-06
        • 2017-12-15
        • 1970-01-01
        相关资源
        最近更新 更多