在Java中捕获NullPointerException异常

28

我尝试使用try-catch块来捕获NullPointerException,但是仍然出现错误。我做错了什么还是有其他方法可以在下面的程序中捕获NullPointerException?非常感谢任何帮助。

public class Circular_or_not 
{

    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        try
        {
            LinkedListNode[] nodes = new LinkedListNode[10];            
            for (int i = 0; i < 10; i++) 
            {
                nodes[i] = new LinkedListNode(i, null, i > 0 ? nodes[i - 1] : null);
            }

            // Create loop;
            // nodes[9].next = nodes[3];
            Boolean abc= Check_Circular(nodes[0]);
            System.out.print(abc);
        }
        catch(NullPointerException e)
        {
            System.out.print("NullPointerException caught");
        }

    }

    public static boolean Check_Circular(LinkedListNode head) 
    {       
            LinkedListNode n1 = head;
            LinkedListNode n2 = head; 

            // Find meeting point
            while (n2.next != null)
            { 
                n1 = n1.next; 
                n2 = n2.next.next; 
                if (n1 == n2) 
                { 
                    return true;
                }
            }
            return false;
    }

}

2
“is giving errors”…你肯定可以说得更具体一些吧? - meriton
不清楚你如何使用LinkedListNode类。例如,像org.jivesoftware.util.LinkedListNode这样的类。 - Mihai8
1
只是一个编码建议。在命名类和方法时,尽量遵循惯例。 - Ankit
1
请参见 https://dev59.com/ZGMl5IYBdhLWcg3wmoDS。 - Raedwald
5个回答

50

NullPointerException是一种运行时异常,不建议捕获它,而是避免它:

if(someVariable != null) someVariable.doSomething();
else
{
    // do something else
}

5
特别是因为整个意图是不要找到想要被找到的东西,所以即使你捕捉到它,它也可能传播到程序的其他部分。 - Jeff Hawthorne

23

正如另一个答案中已经说明的那样,不建议捕获NullPointerException。但是您确实可以捕获它,就像以下示例所示。

public class Testclass{

    public static void main(String[] args) {
        try {
            doSomething();
        } catch (NullPointerException e) {
            System.out.print("Caught the NullPointerException");
        }
    }

    public static void doSomething() {
        String nullString = null;
        nullString.endsWith("test");
    }
}

尽管可以捕获NPE,但您绝不能这样做,而是要解决最初的问题,即Check_Circular方法。

3
你的代码问题在于Check_Circular函数的循环中。你是通过每次向后移动一个节点来使用n1遍历整个列表的。通过将n2重新赋值为n2.next.next,你相当于以每次两个节点的速度遍历整个列表。
这样做可能会导致n2.next.next为空,所以赋值后n2将为null。当循环再次进行并检查n2.next是否不为空时,会抛出NPE异常,因为无法获取下一个节点,而n2已经为null。
你需要像Alex发布的那样进行修改。

2

我认为你的问题在于CheckCircular函数中的while条件:

假设你有两个节点,第一个是N1,第二个是N2,它们都指向同一个节点。然后N1指向了第二个节点(也就是最后一个节点),而N2指向null(因为它是N2.next.next)。在下一次循环中,你试图调用N2的“next”方法,但是N2是null。这就是为什么会出现NullPointerException的原因。


1
你应该使用上述代码捕获NullPointerException,但这并不改变你的Check_Circular是错误的事实。如果你修复了Check_Circular,你的代码就不会首先抛出NullPointerException,而是按照预期工作。
尝试:
public static boolean Check_Circular(LinkedListNode head)
{
    LinkedListNode curNode = head;
    do
    {
        curNode = curNode.next;
        if(curNode == head)
            return true;
    }
    while(curNode != null);

    return false;
}

2
你不应该捕获NPEs。 - elToro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接