2016-08-22 23 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(); 
}