2012-01-31 2 views
5

Я ищу быстрый способ выяснить, какая часть 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, но я хотел бы как-то разобраться с существующим кодом.)

+1

Что вы хотите в качестве вывода? Hashcode цепи, содержащей null? –

+0

Я хочу что-то вроде «c1.returnChain(). ReturnChain() возвращается null». –

+0

@ChristianJonassen: Вы ищете решение для этой конкретной части кода или для чего-то более общего, где вы делаете последовательность вызовов произвольных функций? – Dawood

ответ

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...

+0

Я пробовал то же самое, но это не сработало для меня! Я зарегистрировал 1-ю строчку конструкции, где выброшен NPE. – thermz

+0

Помогает ли кто-нибудь объяснить нижний предел? Я не возражаю, если я ошибаюсь в чем-то, но мне бы хотелось хотя бы объяснить. – Dave

+0

@thermz, не могли бы вы опубликовать код, когда вы это пробовали, и это не сработало? – Dave

0

Может быть, я этого не понимаю, но что около returnChain() == null?

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. Simpler версия:

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

Я не думаю, что Христиану Йонассену нужно решение для этого конкретного кода (что явно является примером), я думаю, что он ищет решение, которое всегда найдет NPE в «цепном» вызове методов .. что-то например, getAway(). getAvenue(). getNumber(). getFloor() ', если avenue имеет значение null, нет никакого хорошего решения для поиска всегда, где NPE выбрасывается .., если вы не хотите попробовать и ловить каждый вызов ... – thermz

+0

Для этого сценария вы можете использовать 'npe.getStackTrace() [0] .getMethodName()'. Конечно, здесь не помогает. –

+0

К сожалению нет, в этой ситуации (владелец кода вопроса), вызывающего 'npe.getStackTrace() [0] .getMethodName()' будет возвращать «main» – thermz

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); 

Это будет пр. INT:

firstChain.returnChain().returnChain() returned null 
0

Без изменения класса Chain, вы можете сделать это, чтобы выяснить, какая часть равна нулю:

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 

Или вы можете просто поймать нулевое исключение указатель на печать пустой

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  
Смежные вопросы