Метод по умолчанию возвращает true на некоторое время, а затем возвращает false? (Возможная ошибка JVM)
У меня проблема со следующим кодом, который я выделил для самой закрытой формы, я использую Java 8, который почти готов к запуску (18 марта 2014 года), поэтому я не ожидаю серьезных проблем в самой реализации, поэтому он может/должен быть моим собственным кодом:
Примечание. Код написан на Java 8, который имеет всевозможные новые функции, включая реализацию метода default
в интерфейсах.
public abstract class Drawable implements DrawableInterface {
}
interface DrawableInterface {
default public boolean isShadowReceiver() {
return false;
}
default public boolean isShadowCaster() {
return false;
}
}
public interface ShadowDrawable extends DrawableInterface {
@Override
default public boolean isShadowReceiver() {
return true;
}
@Override
default public boolean isShadowCaster() {
return true;
}
}
public class Box extends Drawable implements ShadowDrawable {
}
public class IsolatedBug {
private final Box box;
private final List<Drawable> drawables;
public IsolatedBug() {
this.box = new Box();
this.drawables = new ArrayList<>();
drawables.add(box);
drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
}
private void init() throws InterruptedException {
while (true) {
drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
Thread.sleep(100);
}
}
public static void main(String[] args) throws InterruptedException {
new IsolatedBug().init();
}
}
Код сам по себе может не иметь особого смысла, но это связано с тем, что я отключил загрузку других нерелевантных методов.
Однако, когда вы наблюдаете вывод, вы видите что-то странное, в определенный момент, для меня лично через 30 секунд, я вижу следующее:
[email protected] C = true/R = true
[email protected] C = true/R = true
[email protected] C = true/R = true
[email protected] C = true/R = true
[email protected] C = false/R = false
[email protected] C = false/R = false
[email protected] C = false/R = false
[email protected] C = false/R = false
[email protected] C = false/R = false
[email protected]0 C = false/R = false
Время, когда он переключается с true
на false
, похоже, зависит от количества вызовов метода, как и при длительных снах между ними, требуется больше времени для переключения.
Я запускаю это, для получения полной информации о 64-разрядной версии Windows 8 с помощью java -version
:
java version "1.8.0"
Java (TM) SE Runtime Environment (сборка 1.8.0-b129)
Java HotSpot (TM) 64-разрядная серверная VM (сборка 25.0-b69, смешанный режим)
Кто-нибудь может объяснить мне, что происходит?
Я также был бы признателен, если бы другие с Java 8 -any build-, могли запускаться и видеть, имеют ли они одну и ту же проблему.
Дополнительная информация после использования этого кода:
Properties p = System.getProperties();
p.list(System.out);
Вывод:
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0\jre\bin
java.vm.version=25.0-b69
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=NL
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\Frank\Dropbox\NetbeansProjec...
java.runtime.version=1.8.0-b129
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
os.arch=amd64
java.io.tmpdir=C:\Users\Frank\AppData\Local\Temp\
line.separator=
java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 8.1
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jdk1.8.0\bin;C:...
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.3
user.home=C:\Users\Frank
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=UTF-8
java.specification.version=1.8
user.name=Beheerder
java.class.path=C:\Users\Frank\Dropbox\NetbeansProjec...
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=C:\Program Files\Java\jdk1.8.0\jre
sun.java.command=isolatedbug.IsolatedBug
java.specification.vendor=Oracle Corporation
user.language=nl
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0
java.ext.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
sun.boot.class.path=C:\Program Files\Java\jdk1.8.0\jre\li...
java.vendor=Oracle Corporation
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=amd64
Я также проверил опцию -Xint
VM, когда она была использована, она возвращает true
, как ожидалось.
Таким образом, вывод заключается в том, что в моем конкретном случае использования интерпретируемые и JIT-скомпилированные/встроенные варианты кода не совпадают, и, следовательно, возможно, что после компиляции интерпретируемого кода он переключается с интерпретированного на скомпилированный и, таким образом, уточнение переключателя на выходе.
Добавление опции -Xint
в фактическую программу, в которой произошла ошибка, также устранила проблему.
Официальный отчет об ошибке был принят: JIRA Bug JDK-8036100
Ответы
Ответ 1
Это известная ошибка в Java8.
См. этот Jira: CHA игнорирует методы по умолчанию во время анализа, приводящие к неправильной генерации кода
Эта запись в блоге просвещает....
Обновление/сводка:
Предыдущие заметки
Я воспроизвел эту проблему с помощью:
Утверждения, что эта проблема разрешена в b127, запутываются, так как я вижу это четко в b129 (если я не смущен об условных обозначениях JVM...)
C:\Java8\jdk-1.8.0_01\bin>java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)
C:\Java8\jdk-1.8.0_01\bin>
Добавление System.out.println(System.getProperties());
{
java.runtime.name=Java(TM) SE Runtime Environment,
java.runtime.version=1.8.0-b129,
java.vm.specification.name=Java Virtual Machine Specification,
java.vm.name=Java HotSpot(TM) 64-Bit Server VM,
java.vm.version=25.0-b69,
java.vm.vendor=Oracle Corporation,
java.vendor.url=http://java.oracle.com/,
java.vm.specification.version=1.8,
java.specification.name=Java Platform API Specification,
java.specification.version=1.8,
java.specification.vendor=Oracle Corporation,
java.class.version=52.0,
sun.boot.library.path=C:\Java8\jdk-1.8.0_01\jre\bin,
sun.java.launcher=SUN_STANDARD,
sun.os.patch.level=Service Pack 1,
java.endorsed.dirs=C:\Java8\jdk-1.8.0_01\jre\lib\endorsed,
os.arch=amd64,
java.vm.specification.vendor=Oracle Corporation,
os.name=Windows 7,
sun.jnu.encoding=Cp1252,
java.library.path=C:\Java8\jdk-1.8.0_01\bin;......,
sun.management.compiler=HotSpot 64-Bit Tiered Compilers,
os.version=6.1,
file.encoding=UTF-8,
sun.java.command=fromso.IsolatedBug,
java.home=C:\Java8\jdk-1.8.0_01\jre,
sun.arch.data.model=64,
user.language=en,
java.ext.dirs=C:\Java8\jdk-1.8.0_01\jre\lib\ext;C:\windows\Sun\Java\lib\ext,
sun.boot.class.path=C:\Java8\jdk-1.8.0_01\jre\lib\resources.jar;......,
java.vendor=Oracle Corporation,
file.separator=\,
java.vendor.url.bug=http://bugreport.sun.com/bugreport/,
sun.io.unicode.encoding=UnicodeLittle,
sun.cpu.endian=little,
sun.desktop=windows,
sun.cpu.isalist=amd64
}