java - 编译 Java 类时禁用编译时依赖性检查

标签 java jvm bytecode javac

考虑以下两个 Java 类:

a.) class Test { void foo(Object foobar) { } }

b.) class Test { void foo(pkg.not.in.classpath.FooBar foobar) { } }

此外,假设在类路径中找不到 pkg.not.in.classpath.FooBar

第一个类将使用标准 javac 编译得很好。

但是,第二个类不会编译,javac 会给你错误信息 “package pkg.not.in.classpath does not exist”

错误消息在一般情况下很好,因为检查依赖项允许编译器告诉您是否有一些方法参数错误等。

虽然这种在编译时检查依赖关系的方式很好而且很有帮助,但 AFAIK 并不是生成上述示例中的 Java 类文件严格所必需的。

  1. 如果不执行编译时依赖性检查,在技术上不可能生成有效的 Java 类文件,您能举出任何例子吗?

  2. 您知道有什么方法可以指示 javac 或任何其他 Java 编译器跳过编译时依赖性检查吗?

请确保您的回答解决了这两个问题。

最佳答案

Can you give any example for which it would be technically impossible to generate a valid Java class file without performing compile time dependency checking?

考虑这段代码:

public class GotDeps {
  public static void main(String[] args) {
    int i = 1;
    Dep.foo(i);
  }
}

如果目标方法具有签名public static void foo(int n),那么将生成这些指令:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   invokestatic    #16; //Method Dep.foo:(I)V
   6:   return

如果目标方法具有签名public static void foo(long n),则int 将被提升为long prior到方法调用:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   istore_1
   2:   iload_1
   3:   i2l
   4:   invokestatic    #16; //Method Dep.foo:(J)V
   7:   return

在这种情况下,将无法生成调用指令或如何填充类常量池中由数字 16 引用的 CONSTANT_Methodref_info 结构。参见 class file format在 VM 规范中了解更多详细信息。

关于java - 编译 Java 类时禁用编译时依赖性检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1537714/

相关文章:

java - 无法比较字符

java - EditText的onClick关闭android默认键盘

java - 为什么JVM仍然不支持尾调用优化?

java - 字节码中的类型

java - IntelliJ 不接受 Java8 和 List/Map 末尾的菱形

java - java中子字符串索引越界

java - 为什么运行无限循环的非守护线程会停止?

jvm - 如何在程序中实现可移植 JVM?

java - 访问 Nashorn 生成的字节码

java - 未使用的导入和对象是否会对性能产生影响?