在方法调用链中查找null

时间:2012-01-31 21:32:52

标签: java exception null

我正在寻找一种快速的方法来确定chain的哪一部分为空。

示例来说明要点:

public class Chain {
    private Chain chain;

    public Chain returnChain() {
        return chain;
    }

    public void addChain(Chain chain) {
        this.chain=chain;
    }

    public String toString() {
        return "Hello!";
    }

    public static void main(String[] args) {
        Chain c1 = new Chain();
        c1.addChain(new Chain());

        System.out.println(c1.returnChain().returnChain().returnChain().returnChain());
    }
}

这显然会抛出一个NullPointerException。 (我知道如何更改代码以明确链接的哪一部分抛出NullPointerException,但我想用现有代码来解决这个问题。)

5 个答案:

答案 0 :(得分:2)

在典型NPE的堆栈跟踪中,您将获得它所发生的行号。因此,假设System.out.println(c1.returnChain().returnChain().returnChain().returnChain());位于第144行(只是随机选取),您的NPE堆栈跟踪应该类似于:

java.lang.NullPointerException
  at your.package.Chain(Chain.java:144)

因此,如果您将链调用放在多行上,它应该显示异常的位置。

我写了这个小例子:

package bla;

public class Something {
    public static int count = 0;
    public Something get() {
        if(count == 2) {
            return null;
        }
        ++count;
        return new Something();
    }

    public static void main(String[] args){
        Something something = new Something();
        Something test = something.get()
                                .get()
                                    .get()
                                        .get() // Should throw NPE
                                            .get()
                                                .get();
    }
}

它给了我NPE说:在bla.Something.main(Something.java:18) - 确切地说NPE在链中发生的地方。

屏幕截图...

Showing what this would look like...

答案 1 :(得分:2)

对于您拥有的特定代码,请尝试将以下方法添加到Chain类:

    public static Chain checkChainSequence(Chain first, int count) {
        Chain thisChain = first;
        StringBuilder out = new StringBuilder("firstChain");
        for (int i = 0; i < count; i++) {
            Chain nextChain = thisChain.returnChain();
            out.append(".returnChain()");
            if (nextChain == null) {
                out.append(" returned null");
                System.out.println(out);
                return null;
            }
            thisChain = nextChain;
        }
        return thisChain;
    }

您可以按如下方式使用它:

    Chain c1 = new Chain();
    c1.addChain(new Chain());

    // To check c1.returnChain().returnChain().returnChain():
    Chain.checkChainSequence(c1, 3);

这将打印:

    firstChain.returnChain().returnChain() returned null

答案 2 :(得分:0)

也许我没有得到它,但仅仅是returnChain() == null

答案 3 :(得分:0)

您可以添加Chain类变量,例如position来确定链中元素的位置:

public class Chain {
    private Chain chain;
    private int position;

    public Chain returnChain() {
        if (chain == null) {
            System.out.println(position + " chain is null");
        } else {
            chain.position = position + 1;
        }
        return chain;
    }

    public void addChain(Chain chain) {
        this.chain=chain;
    }

    public String toString() {
        return "Hello!";
    }

    public static void main(String[] args) {
        Chain c1 = new Chain();
        c1.addChain(new Chain());
        c1.position = 0;
        System.out.println(c1.returnChain().returnChain().returnChain().returnChain());
    }
}

当然它不是线程安全的,看起来很奇怪。但是应该写出null的位置。 更简单的版本:

public int findPositionOfNullChain(Chain chain) {
     int position = 0;
     while (chain != null) {
         chain = chain.returnChain();
         position++;
     }
     return position;
}

答案 4 :(得分:0)

如果不修改Chain类,可以执行此操作以找出哪个部分为null:

Chain c1 = new Chain();
c1.addChain(new Chain());
Chain preNullChain = c1;
Chain returnedChained = null;

while ((returnedChained = preNullChain.returnChain()) != null) {
    preNullChain = returnedChained;
}
//here, preNullChain is the last Chain that is not null

或者您可以捕获空指针异常以打印null

Chain returnedChain = null;
Chain c1 = new Chain();
c1.addChain(new Chain());
try {
returnedChain = c1.returnChain().returnChain().returnChain().returnChain();
} catch (NullPointerException e) {
}
System.out.println(returnedChain); //now here will print null as what you asked for