有人可以在下面的示例代码中解释导致NPE的原因。这似乎与静态字段(特别是Predicate
)的初始化方式有关,但我无法弄清楚发生了什么。
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 :(得分:2)
见JLS-12.4.2
。静态字段初始化的顺序很重要。字段按照它们在源中出现的顺序进行初始化。
因此,doStuff()
调用时bar
等于默认值null
。
答案 1 :(得分: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;
}
}
答案 2 :(得分:0)
初始化顺序为:
以下是解决问题的方法:
public static List<Integer> stuff;
private static Predicate<Integer> bar;
static {
bar = i -> i == 42;
stuff = doStuff();
}