编程语言
首页 > 编程语言> > 为什么Java 1.0.2中的Interface Member没有设置ACC_ABSTRACT?

为什么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 its ACC_FINAL flag set.

JVM规范has similar words to say的版本9:

If the ACC_INTERFACE flag is set, the ACC_ABSTRACT flag must also be set, and the ACC_FINAL, ACC_SUPER, ACC_ENUM, and ACC_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