为什么Java 1.0.2中的Interface Member没有设置ACC_ABSTRACT?
作者:互联网
我编写了一个简单的Java字节码解析器进行一些实验,最近它在一个意外的地方失败了.从Java 1.1.8.16的rt.jar读取java / lang / reflect / Member.java时,我的解析器很生气,因为Member像这样开始(请注意缺少的ACC_ABSTRACT标志):
Classfile Member.class
Last modified Aug 8, 2002; size 350 bytes
MD5 checksum 9a1aaec8e70e9a2ff9d63331cb0ea34e
Compiled from "Member.java"
public interface java.lang.reflect.Member
minor version: 3
major version: 45
flags: (0x0201) ACC_PUBLIC, ACC_INTERFACE
...
Java 1.2.2.17的版本对此进行了更正,并将标志设置为0x0601(ACC_ABSTRACT | ACC_INTERFACE | ACC_PUBLIC).
我可以找到的最早的JVM规范(据说是1.0.2)有这样的说法(§4.1,第86页,增加了重点):
An interface is implicitly abstract (§2.13.1); its
ACC_ABSTRACT
flag must be set. An interface cannot be final; its implementation could never be completed (§2.13.1) if it were, so it could not have itsACC_FINAL
flag set.
JVM规范has similar words to say的版本9:
If the
ACC_INTERFACE
flag is set, theACC_ABSTRACT
flag must also be set, and theACC_FINAL
,ACC_SUPER
,ACC_ENUM
, andACC_MODULE
flags set must not be set.
Oracle / Sun JVM是否强制执行“必须存在”这样的要求?如果是这样,什么时候开始?如果不是,为什么JVM规范会假装要求它呢?
解决方法:
这是一个错误JDK-4059153:javac没有为接口设置ACC_ABSTRACT.
该错误已在1.2中修复,但是由于已经有许多与此错误一起编译的类,因此JVM获得了一种变通方法,可为具有ACC_INTERFACE的所有类自动添加ACC_ABSTRACT.直到Java 6最终决定严格遵循新类文件的规范后,这种方法一直有效.但是,为了与旧版本的类文件向后兼容,该解决方法直到现在仍存在,请参阅classFileParser.cpp:
if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
// Set abstract bit for old class files for backward compatibility
flags |= JVM_ACC_ABSTRACT;
}
标签:class-file,jvm,jvm-bytecode,java,bytecode 来源: https://codeday.me/bug/20191025/1928985.html