-1

Could someone explain what is causing the NPE in the following example code. It seems to be something to do with how static fields (in particular the Predicate) are initialized maybe, but I can't quite figure out what is going on.

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();
    }
}
glp
  • 116
  • 1
  • 1
  • 12

3 Answers3

2

See JLS-12.4.2. The order of static fields initialization matters. Fields are initialized in the order in which they appear in the source.

So at the moment doStuff() is called bar is equals to default value null.

vsminkov
  • 10,912
  • 2
  • 38
  • 50
1

You are calling to bar before it has been initialized, try this:

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;
    }
}
David Pérez Cabrera
  • 4,960
  • 2
  • 23
  • 37
0

Sequence of initialization is:

  • Execution of method doStuff (here bar is not yet initialized)
  • Assignement of stuff variable
  • Assignement of bar variable

Here is how you can solve it:

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

static  {
    bar = i -> i == 42;
    stuff = doStuff();
}
Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56