为什么它给我一个 return 缺失错误?
Why is it giving me a return missing error?
为什么这个方法总是告诉我它缺少 return 语句?如果我删除 else,它会告诉我无法访问 return true。预先感谢您的帮助!
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
Why does this method keep telling me it's missing a return statement ?
因为在for
循环之后有办法到达那个点。考虑 pass
的长度为零的情况。
更一般地说,JLS 14.22 中列出了确定语句(或代码中的点)可达性的规则。一个简单的for
循环的相关规则如下:
A basic for
statement can complete normally if and only if at least one of the following is true:
- The
for
statement is reachable, there is a condition expression, and the condition expression is not a constant expression (§15.29) with value true.
- There is a reachable break statement that exits the
for
statement.
在您的示例中,满足了第一个要求。因此,for
循环可以正常完成。因此在 for
循环之后有一个 return 点。因此,此时需要 return
语句。
请注意,可达性规则不依赖于 Java 编译器是否足够聪明来分析您的应用程序的逻辑,并且它们不会赋予编译器聪明的判断力。因此,有 Java 个示例,其中可以 正式证明 一个语句是不可访问的,但规则说它仍然是可访问的,并要求编译错误。
(因此在您的示例中,编译器不需要推断您的代码没有考虑零长度字符串。这是“人类水平”的推理。)
它在抱怨,因为你在循环结束时缺少一个 return。您的方法可以在三种不同的情况下退出,即:
- 当字符串
pass
不为空且首字符不为
一个数字;
- 当字符串
pass
不为空且首字符为数字时;
- 当字符串为空时!.
在代码中:
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false; // <--- can exit here
}
else
return true; // <-- can exit here
}
// <-- can exit here if the string pass is empty
}
您涵盖了前两种情况,但没有涵盖第三种情况(即,当字符串为空时)。
现在,由于 Java 规则 "for determining the reachability of a statement" 正如@Stephen C 首先指出的(并且已经解释得很好,并且改进我的答案的灵感来源)逻辑上涵盖三个场景 单独 不会使您的代码编译干净。例如:
public static boolean Digit(String pass){
if(pass.isEmpty())
return false;
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
在上面的代码中,所有可能的退出点都被覆盖了,尽管如此,我的 IDE 仍然抱怨缺少 return 语句。为什么?因为根据上述规则,这个循环可以正常完成,因此需要在if的末尾添加一个return
。但是,使用相同的语义相同代码:
public static boolean Digit(String pass){
if(pass.isEmpty())
return false;
for (int i = 0; true; i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
它编译得很好,即使在循环结束时没有 returning 语句。为什么?因为根据上述规则,我的循环无法再正常完成,因为它的条件表达式是 true
,可以找到有关它的更多详细信息 here。平心而论,我的 IDE,只要我添加了您的代码,我就立即收到警告 'for' statement does not loop
.
总而言之,对于您的情况,您需要涵盖三种情况,并在循环结束时有一个 return 语句,您可以阅读有关 here 或@Stephen C 的更多信息答案很好地分解了它。
除此之外,您的方法并没有按照您的意愿行事。您只比较字符串的第一个数字,但您应该检查整个字符串,例如:
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
}
return !pass.isEmpty();
}
您只想 return
当您发现一个不是数字的字符或(在循环结束时)检查了整个字符串后。我正在 returning !pass.isEmpty();
以确保我们不会 return true
如果字符串为空。使用当前代码,我们涵盖了所有出口点,即:
- 如果字符串仅包含数字,您将到达语句
return !pass.isEmpty();
,因此 return true
;
- 如果字符串至少包含一个非数字,你将达到
return false;
;
- 如果字符串为空,您将到达
return !pass.isEmpty();
,因此 return false
。
附带说明,您应该将方法的名称从 Digit
更改为 isAllDigits
,后者比前者更明确。
另一个旁注,使用 Java Streams,您可以将方法简化为:
public static boolean isDigit(String pass){
return !pass.isEmpty() && pass.chars().allMatch(Character::isDigit);
}
为什么这个方法总是告诉我它缺少 return 语句?如果我删除 else,它会告诉我无法访问 return true。预先感谢您的帮助!
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
Why does this method keep telling me it's missing a return statement ?
因为在for
循环之后有办法到达那个点。考虑 pass
的长度为零的情况。
更一般地说,JLS 14.22 中列出了确定语句(或代码中的点)可达性的规则。一个简单的for
循环的相关规则如下:
A basic
for
statement can complete normally if and only if at least one of the following is true:
- The
for
statement is reachable, there is a condition expression, and the condition expression is not a constant expression (§15.29) with value true.- There is a reachable break statement that exits the
for
statement.
在您的示例中,满足了第一个要求。因此,for
循环可以正常完成。因此在 for
循环之后有一个 return 点。因此,此时需要 return
语句。
请注意,可达性规则不依赖于 Java 编译器是否足够聪明来分析您的应用程序的逻辑,并且它们不会赋予编译器聪明的判断力。因此,有 Java 个示例,其中可以 正式证明 一个语句是不可访问的,但规则说它仍然是可访问的,并要求编译错误。
(因此在您的示例中,编译器不需要推断您的代码没有考虑零长度字符串。这是“人类水平”的推理。)
它在抱怨,因为你在循环结束时缺少一个 return。您的方法可以在三种不同的情况下退出,即:
- 当字符串
pass
不为空且首字符不为 一个数字; - 当字符串
pass
不为空且首字符为数字时; - 当字符串为空时!.
在代码中:
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false; // <--- can exit here
}
else
return true; // <-- can exit here
}
// <-- can exit here if the string pass is empty
}
您涵盖了前两种情况,但没有涵盖第三种情况(即,当字符串为空时)。
现在,由于 Java 规则 "for determining the reachability of a statement" 正如@Stephen C 首先指出的(并且已经解释得很好,并且改进我的答案的灵感来源)逻辑上涵盖三个场景 单独 不会使您的代码编译干净。例如:
public static boolean Digit(String pass){
if(pass.isEmpty())
return false;
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
在上面的代码中,所有可能的退出点都被覆盖了,尽管如此,我的 IDE 仍然抱怨缺少 return 语句。为什么?因为根据上述规则,这个循环可以正常完成,因此需要在if的末尾添加一个return
。但是,使用相同的语义相同代码:
public static boolean Digit(String pass){
if(pass.isEmpty())
return false;
for (int i = 0; true; i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
else
return true;
}
}
它编译得很好,即使在循环结束时没有 returning 语句。为什么?因为根据上述规则,我的循环无法再正常完成,因为它的条件表达式是 true
,可以找到有关它的更多详细信息 here。平心而论,我的 IDE,只要我添加了您的代码,我就立即收到警告 'for' statement does not loop
.
总而言之,对于您的情况,您需要涵盖三种情况,并在循环结束时有一个 return 语句,您可以阅读有关 here 或@Stephen C 的更多信息答案很好地分解了它。
除此之外,您的方法并没有按照您的意愿行事。您只比较字符串的第一个数字,但您应该检查整个字符串,例如:
public static boolean Digit(String pass){
for (int i=0; i < pass.length(); i++ ){
if (!Character.isDigit(pass.charAt(i))) {
System.out.println("Must contain digits");
return false;
}
}
return !pass.isEmpty();
}
您只想 return
当您发现一个不是数字的字符或(在循环结束时)检查了整个字符串后。我正在 returning !pass.isEmpty();
以确保我们不会 return true
如果字符串为空。使用当前代码,我们涵盖了所有出口点,即:
- 如果字符串仅包含数字,您将到达语句
return !pass.isEmpty();
,因此return true
; - 如果字符串至少包含一个非数字,你将达到
return false;
; - 如果字符串为空,您将到达
return !pass.isEmpty();
,因此return false
。
附带说明,您应该将方法的名称从 Digit
更改为 isAllDigits
,后者比前者更明确。
另一个旁注,使用 Java Streams,您可以将方法简化为:
public static boolean isDigit(String pass){
return !pass.isEmpty() && pass.chars().allMatch(Character::isDigit);
}