我正在开始Java课程,并在测试我为课程编写的程序时偶然发现了一个看似错误的内容。我不需要家庭作业的帮助。我想了解有关null的两件事和解析null的一件事。
首先,当您运行我的示例代码时,您会看到单击swing输入框上的“OK”按钮而没有任何输入存储一个看似为null的字符串值。但是,当测试字符串时,它不会测试为null。这是为什么?
其次,当您运行我的示例代码时,您会看到单击swing输入框上的“Cancel”按钮会存储一个看似是包含文本“null”的字符串的值。这会测试为空值,但是包含文本“null”的字符串显然不会测试为null。当我认为空字符串值是“?”时,为什么取消按钮会生成一个文本为“null”的字符串?
最后,当您运行我的示例代码时,您将看到被测试为null的值在被解析为double时抛出NullPointerException,但是当它们被解析为int时它们不会抛出NullPointerException。这是为什么?
我的老师无法回答这些问题。他认为示例程序中的解析是算术完成的,因此int可能表现不同,因为它们不处理小数点。这对我来说是有道理的,但是如果是这样的话,为什么他们用null解析不同的字符串如何回答=“”;和取消按钮生成的null?
我的示例代码如下:
import javax.swing.*;
public class NullTest {
public static void main(String[] args) {
//Demonstrate behavior with doubles.
throwingDoubles();
//Demonstrate behavior with integers.
throwingInts();
}
public static void throwingDoubles()
{
//Loops three times so you can test each option.
for (int i = 0; i < 3; i++)
{
JOptionPane.showMessageDialog(null, "Double Tester\nFirst time through click ok without entering text.\nSecond time through click cancel.\nFinally type in null to prove that this string is not treated as a null value.");
String answer = JOptionPane.showInputDialog(null, "I would think 'answer' would be null if you click ok without entering anything.");
JOptionPane.showMessageDialog(null, "Double Tester\n'" + answer + "'\nIt appears null here if you don't enter anything, but as a string if you click cancel");
if (answer==null)
{
JOptionPane.showMessageDialog(null, "Double Tester\nTested null");
JOptionPane.showMessageDialog(null, "Double Tester\n'" + answer + "'\nIt appears the same here.");
}
else
{
JOptionPane.showMessageDialog(null, "Double Tester\nDid not test null");
JOptionPane.showMessageDialog(null, "Double Tester\n'" + answer + "'\nIt appears the same here.");
}
try
{
double varDoub = Double.parseDouble(answer);
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "Double Tester\nThis threw a NumberFormatException");
}
catch(NullPointerException e)
{
JOptionPane.showMessageDialog(null, "Double Tester\nThis threw a NullPointerException");
}
//An early escape clause.
if (JOptionPane.showConfirmDialog(null, "Run the loop again?")!=JOptionPane.OK_OPTION)
{
break;
}
}
}
public static void throwingInts()
{
//Loops three times so you can test each option.
for (int i = 0; i < 3; i++)
{
JOptionPane.showMessageDialog(null, "Int Tester\nFirst time through click ok without entering text.\nSecond time through click cancel.\nFinally type in null to prove that this string is not treated as a null value.");
String answer = JOptionPane.showInputDialog(null, "Int Tester\nI would think 'answer' would be null if you click ok without entering anything.");
JOptionPane.showMessageDialog(null, "Int Tester\n'" + answer + "'\nIt appears null here if you don't enter anything, but as a string if you click cancel");
if (answer==null)
{
JOptionPane.showMessageDialog(null, "Int Tester\nTested null");
JOptionPane.showMessageDialog(null, "Int Tester\n'" + answer + "'\nIt appears the same here.");
}
else
{
JOptionPane.showMessageDialog(null, "Int Tester\nDid not test null");
JOptionPane.showMessageDialog(null, "Int Tester\n'" + answer + "'\nIt appears the same here.");
}
try
{
int varDoub = Integer.parseInt(answer);
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog(null, "Int Tester\nThis threw a NumberFormatException");
}
catch(NullPointerException e)
{
JOptionPane.showMessageDialog(null, "Int Tester\nWe never see this code. Why not?");
}
//An early escape clause.
if (JOptionPane.showConfirmDialog(null, "Run the loop again?")!=JOptionPane.OK_OPTION)
{
break;
}
}
}
}
答案 0 :(得分:3)
首先,当您运行我的示例代码时,您会看到单击swing输入框上的“OK”按钮而没有任何输入存储一个看似为null的字符串值。但是,当测试字符串时,它不会测试为null。这是为什么?
因为空字符串与null不同。当没有文字时点击“确定”,你接受一个空字符串作为你提供的值。当您按“取消”时,您实际上是在说“我拒绝提供值” - 这就是为什么返回值记录为:
用户输入,或null表示用户取消了输入
下一步:
其次,当您运行我的示例代码时,您会看到单击swing输入框上的“Cancel”按钮会存储一个看似是包含文本“null”的字符串的值。这会测试为空值,但是包含文本“null”的字符串显然不会测试为null。当我认为空字符串值是“?”时,为什么取消按钮会生成一个文本为“null”的字符串?
不,它存储的值为空引用。空引用不与对“”或“null”的引用相同。但在字符串连接中,空引用将转换为“null”:"a" + null + "b"
最终将为"anullb"
。
了解引用如何在Java中工作非常重要。引用是一种有效地导航到对象的方式......并且空引用是一种说法,“没有对象可以导航到”。如果您认为带有参考值的变量就像一张写有街道地址的纸张,如果该值为空,则纸张为空白。
最后,当您运行我的示例代码时,您将看到被测试为null的值在被解析为double时抛出NullPointerException,但是当它们被解析为int时它们不会抛出NullPointerException。这是为什么?
看起来它只是API中的一点不一致。 Integer.parseInt
会引发NumberFormatException
。两者都表现得如同记录。
答案 1 :(得分:0)
我想你的问题就在这里:
JOptionPane.showMessageDialog(null, "Double Tester\n'" + answer + "'\nIt appe...
^^^^^^
如果answer
为null
(用户已按Cancel
),则该消息将显示为:
双测试仪
空
它... ...
然而如果用户使用空输入字段按Ok
,answer
引用空字符串(""
),因此给予:
Double Tester
它赞成......
问题是您混淆了null
引用("null"
)和空字符串(""
)的字符串值。