Следующий код меня сильно озадачивает.
import java.util.function.Predicate;
public class Test {
private final Predicate<String> filter = s -> s != null;
private boolean started = false;
private class Runner implements Runnable {
@Override
public void run() {
synchronized ( Test.this ) {
started = true;
Test.this.notifyAll();
traverse("");
}
}
}
public Test() {
System.out.println(filter.test(""));
Thread thread = new Thread(new Runner());
thread.setDaemon(true);
thread.start();
}
public synchronized String start() {
while ( !started ) {
try {
wait();
} catch ( InterruptedException ex ) {}
}
return "";
}
private synchronized void traverse(String s) {
filter.test(""); // DOES NOT COMPUTE
filter.test(s);
System.out.println("not here");
}
private static final String STRING = new Test().start(); // POS1
public static void main(String[] args) {
System.out.println(STRING); // POS2
}
}
Он застрял на DOES NOT COMPUTE
.Однако, если я удаляю строку POS1
и изменяю POS2
на System.out.println(new Test().start())
, она работает безупречно.В приведенном выше коде filter
, по-видимому, не оценивает, инициируется ли Test
через статическую переменную.
Почему это так и как это можно исправить, пожалуйста?