2

由于无论定义如何存在,静态函数调用都会被转换为静态调用字节码......即使目标函数和类还不存在,是否有某种方法可以强制静态函数的调用者成功编译?

我希望能够编译对尚不存在的函数的调用。我需要告诉编译器相信我,在运行时,我会在类路径中正确定义它们,所以现在继续编译它。

有没有办法做到这一点?

4

3 回答 3

4

反思是的,但不是通过常规电话。

该调用需要字符串池中包含方法名称和参数类型的条目,因此编译器需要能够决定该方法的签名。

invokestatic <方法规范>

<method-spec> 是一个方法规范。它是由三部分组成的单个标记:类名、方法名和描述符。例如

 java/lang/System/exit(I)V

是名为“java.lang.System”的类中名为“exit”的方法,它具有描述符“(I)V”(即它接受一个整数参数并且不返回结果)。

考虑

AClass.aStaticMethod(42)

在不知道任何事情的情况下AClass,它可能是对任何一个的调用

  1. AClass.aStaticMethod(int)
  2. AClass.aStaticMethod(int...)
  3. AClass.aStaticMethod(long)
  4. AClass.aStaticMethod(long...)
  5. 同上float_double
  6. AClass.aStaticMethod(Integer)
  7. AClass.aStaticMethod(Number)
  8. AClass.aStaticMethod(Comparable<? extends Integer>)
  9. AClass.aStaticMethod(Object)
  10. AClass.aStaticMethod(Serializable)

可能还有一些我错过的。

于 2012-09-16T00:08:57.353 回答
2

...是否有某种方法可以强制静态函数的调用者成功编译,即使目标函数和类还不存在?

不可以。编译方法调用时,编译器需要检查被调用方法的名称、参数类型、结果类型、异常等。由于您询问的是静态方法,因此此信息只能在一个地方定义......声明静态方法的类。如果您想要静态类型安全,则没有解决方法。

我需要告诉编译器在运行时相信我......

没那么简单:

  • 您还没有告诉编译器方法签名应该是什么。需要告知编译器,因为无法从调用中准确推断出签名。

  • Java 平台被设计成健壮的,“相信我”可能会导致灾难性的运行时故障。


如果您愿意牺牲编译时类型安全并避开静态类型代码的便利性/简单性/可读性,那么反射是一种选择。但我想不出任何其他可行的选择。

于 2012-09-16T02:11:20.833 回答
0

不,但是您可以声明具有针对它们的方法和代码的接口,然后使用抽象工厂模式在运行时提供实现。

依赖注入使用这种方法。

于 2012-09-16T00:04:16.507 回答