2016-08-22 53 views
-1

有人可以在以下示例代碼中解釋導致NPE的原因。這似乎與靜態字段(特別是Predicate)初始化的方式有關,但我無法弄清楚發生了什麼。在靜態字段初始化期間使用謂詞時出現NullPointerException

import java.util.Arrays; 
import java.util.List; 
import java.util.function.Predicate; 
import java.util.stream.Collectors; 

public class Foo { 
    public static List<Integer> stuff = doStuff(); 
    private static Predicate<Integer> bar = i -> i == 42; 

    public static int howBigIsStuff(){ 
     return stuff.size(); 
    } 

    private static List<Integer> doStuff(){ 
     // java.lang.NullPointerException 
     // at java.util.Objects.requireNonNull(Objects.java:203) 
     List<Integer> foo = Arrays.asList(1,2,42,42).stream() 
       .filter(bar) 
       .collect(Collectors.toList()); 
     return foo; 
    } 
} 


import java.util.Arrays; 
import java.util.List; 
import java.util.function.Predicate; 
import java.util.stream.Collectors; 
import org.junit.Test; 

public class FooTest { 

    private static Predicate<Integer> bar = i -> i == 42; 

    @Test 
    public void test() { 
     // This is fine 
     List<Integer> foo = Arrays.asList(1,2,42,42).stream() 
       .filter(bar) 
       .collect(Collectors.toList()); 
     System.out.println(foo); // [42, 42] 

     Foo.howBigIsStuff(); 
    } 
} 
+0

在哪裏堆棧跟蹤?這可能對大多數人有幫助。 – Orin

回答

1

請參閱JLS-12.4.2。靜態字段初始化的順序很重要。字段按其出現在源中的順序進行初始化。因此目前doStuff()被調用bar等於默認值null

1

你打電話來bar它被初始化之前,試試這個:

public class Foo { 
    private static Predicate<Integer> bar = i -> i == 42; 
    public static List<Integer> stuff = doStuff(); 

    public static int howBigIsStuff() { 
     return stuff.size(); 
    } 

    private static List<Integer> doStuff() { 
     // java.lang.NullPointerException 
     // at java.util.Objects.requireNonNull(Objects.java:203) 
     List<Integer> foo = Arrays.asList(1, 2, 42, 42).stream() 
       .filter(bar) 
       .collect(Collectors.toList()); 
     return foo; 
    } 
} 
0

初始化的順序是:

  • 方法的執行doStuff(此欄尚未初始化)
  • 工具變量
  • 工具變量

這裏是你如何解決這個問題:

public static List<Integer> stuff; 
private static Predicate<Integer> bar; 

static { 
    bar = i -> i == 42; 
    stuff = doStuff(); 
}