由于无论定义如何存在,静态函数调用都会被转换为静态调用字节码......即使目标函数和类还不存在,是否有某种方法可以强制静态函数的调用者成功编译?
我希望能够编译对尚不存在的函数的调用。我需要告诉编译器相信我,在运行时,我会在类路径中正确定义它们,所以现在继续编译它。
有没有办法做到这一点?
由于无论定义如何存在,静态函数调用都会被转换为静态调用字节码......即使目标函数和类还不存在,是否有某种方法可以强制静态函数的调用者成功编译?
我希望能够编译对尚不存在的函数的调用。我需要告诉编译器相信我,在运行时,我会在类路径中正确定义它们,所以现在继续编译它。
有没有办法做到这一点?
反思是的,但不是通过常规电话。
该调用需要字符串池中包含方法名称和参数类型的条目,因此编译器需要能够决定该方法的签名。
invokestatic <方法规范>
<method-spec> 是一个方法规范。它是由三部分组成的单个标记:类名、方法名和描述符。例如
java/lang/System/exit(I)V
是名为“java.lang.System”的类中名为“exit”的方法,它具有描述符“(I)V”(即它接受一个整数参数并且不返回结果)。
考虑
AClass.aStaticMethod(42)
在不知道任何事情的情况下AClass
,它可能是对任何一个的调用
AClass.aStaticMethod(int)
AClass.aStaticMethod(int...)
AClass.aStaticMethod(long)
AClass.aStaticMethod(long...)
float
_double
AClass.aStaticMethod(Integer)
AClass.aStaticMethod(Number)
AClass.aStaticMethod(Comparable<? extends Integer>)
AClass.aStaticMethod(Object)
AClass.aStaticMethod(Serializable)
可能还有一些我错过的。
...是否有某种方法可以强制静态函数的调用者成功编译,即使目标函数和类还不存在?
不可以。编译方法调用时,编译器需要检查被调用方法的名称、参数类型、结果类型、异常等。由于您询问的是静态方法,因此此信息只能在一个地方定义......声明静态方法的类。如果您想要静态类型安全,则没有解决方法。
我需要告诉编译器在运行时相信我......
没那么简单:
您还没有告诉编译器方法签名应该是什么。需要告知编译器,因为无法从调用中准确推断出签名。
Java 平台被设计成健壮的,“相信我”可能会导致灾难性的运行时故障。
如果您愿意牺牲编译时类型安全并避开静态类型代码的便利性/简单性/可读性,那么反射是一种选择。但我想不出任何其他可行的选择。