-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();
    }
}
1
  • Where is the stacktrace? That will probably help the most. Commented Aug 22, 2016 at 14:20

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.