"JOptionPane java.lang.NullPointerException" Java 中的错误
"JOptionPane java.lang.NullPointerException" error in Java
这是我的完整代码:
import javax.swing.JOptionPane;
public class Lab5bug {
public static void main(String[] args) {
int x=0;
String str;
for (;;)
{
str = JOptionPane.showInputDialog("Enter a grade 0-100\n(Hit Cancel to abort)");
if (str==null || str.equals(""))
break;
x = Integer.parseInt(str);
if (x>=0 && x<=100)
break;
JOptionPane.showMessageDialog( null, "Invalid grade, try again");
}
if (str != null & !str.equals("")) //<===========BUG: NEEED TO USE &&
//&,||.| are all lead to bug if we press Cancel.
//str can be null it does not pass 1st condition
//but still pass 2nd condition
//str can be "" pass first condition but not second condition
//and therefre it still show the message The grade is 0
//But why
JOptionPane.showMessageDialog( null, "The grade is " + x);
}
}
当我运行程序在第一个对话框按取消,然后程序returns报错:
Exception in thread "main" java.lang.NullPointerException
at Lab5bug.main(Lab5bug.java:19)
我已经定位到问题所在,在这一行
如果 (str != null & !str.equals(""))
但为什么只有 && 有效?我不明白这背后的逻辑。
替换
if (str != null & !str.equals(""))
和
if (str != null && !str.equals(""))
&
代表按位与。因此,当 str
为 null 时,表达式 !str.equals("")
将抛出 NullPointerException
。当使用逻辑 AND 运算符 &&
时,!str.equals("")
表达式将不会到达,因为第一个条件 str != null
为假。
&
不会短路语句,这意味着如果 str != null
为假,它仍然会尝试 str.equals("")
如果 str
为空,这将导致 NPE。即使第一部分为假,系统也会天真地用 &
评估语句的第二部分。
&&
起作用是因为它使语句短路,如果 str != null
为假,它会中断语句而不评估语句的第二部分并避免 NPE;因为如果第一个值为 false,则该语句就不会为真。
大多数时候 &&
比 &
更受欢迎。
同样的规则也适用于 OR、|
和 ||
。 true | throw new RuntimeException("Second part of statement was evaluated ");
将抛出该异常,而 true || throw new RuntimeException("Second part of the statement was evaluated")
不会到达异常,因为语句保证为真,因为语句的第一部分计算为真,因此它短路并从语句中断。
这是我的完整代码:
import javax.swing.JOptionPane;
public class Lab5bug {
public static void main(String[] args) {
int x=0;
String str;
for (;;)
{
str = JOptionPane.showInputDialog("Enter a grade 0-100\n(Hit Cancel to abort)");
if (str==null || str.equals(""))
break;
x = Integer.parseInt(str);
if (x>=0 && x<=100)
break;
JOptionPane.showMessageDialog( null, "Invalid grade, try again");
}
if (str != null & !str.equals("")) //<===========BUG: NEEED TO USE &&
//&,||.| are all lead to bug if we press Cancel.
//str can be null it does not pass 1st condition
//but still pass 2nd condition
//str can be "" pass first condition but not second condition
//and therefre it still show the message The grade is 0
//But why
JOptionPane.showMessageDialog( null, "The grade is " + x);
}
}
当我运行程序在第一个对话框按取消,然后程序returns报错:
Exception in thread "main" java.lang.NullPointerException
at Lab5bug.main(Lab5bug.java:19)
我已经定位到问题所在,在这一行 如果 (str != null & !str.equals("")) 但为什么只有 && 有效?我不明白这背后的逻辑。
替换
if (str != null & !str.equals(""))
和
if (str != null && !str.equals(""))
&
代表按位与。因此,当 str
为 null 时,表达式 !str.equals("")
将抛出 NullPointerException
。当使用逻辑 AND 运算符 &&
时,!str.equals("")
表达式将不会到达,因为第一个条件 str != null
为假。
&
不会短路语句,这意味着如果 str != null
为假,它仍然会尝试 str.equals("")
如果 str
为空,这将导致 NPE。即使第一部分为假,系统也会天真地用 &
评估语句的第二部分。
&&
起作用是因为它使语句短路,如果 str != null
为假,它会中断语句而不评估语句的第二部分并避免 NPE;因为如果第一个值为 false,则该语句就不会为真。
大多数时候 &&
比 &
更受欢迎。
同样的规则也适用于 OR、|
和 ||
。 true | throw new RuntimeException("Second part of statement was evaluated ");
将抛出该异常,而 true || throw new RuntimeException("Second part of the statement was evaluated")
不会到达异常,因为语句保证为真,因为语句的第一部分计算为真,因此它短路并从语句中断。