解析int和double之间的NullExceptionHandling不同

时间:2012-02-29 07:30:53

标签: java parsing nullpointerexception double int

我正在开始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;
        }
    }
 }

    }

2 个答案:

答案 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...
                                                         ^^^^^^

如果answernull(用户已按Cancel),则该消息将显示为:

  

双测试仪
  空
  它... ...

然而如果用户使用空输入字段按Okanswer引用空字符串""),因此给予:

  

Double Tester

     

它赞成......

问题是您混淆了null引用("null")和空字符串("")的字符串值。