静态语言和反射技术

6
据我所知和理解,反射是在运行时创建/修改源代码的能力。
据维基百科:
  • 以第一类对象的形式发现并修改源代码结构(例如代码块、类、方法、协议等)。
  • 将与类或函数的符号名称匹配的字符串转换为对该类或函数的引用或调用。
  • 评估一个字符串,就像它是在运行时的源代码语句一样。
    为语言的字节码创建一个新的解释器,以赋予编程结构新的含义或目的。
动态语言是我们可以在运行时直接进行eval(评估字符串)的语言。
维基百科说:“通过添加新代码、扩展对象和定义,或修改类型系统来扩展程序。”
现在,我的问题是: 没有eval能力的静态语言如何拥有反射(例如Java)?(新的源代码没有被评估? :/)
提前感谢您!

Java有一个名为ASM的字节码操作库。反射并不用于像您在问题中描述的那样添加新代码。 - Sotirios Delimanolis
1
反射允许查询类的方法、字段、访问级别等并进行篡改(在某些情况下可能会有害),但不会生成新代码。它还有其他用途,例如基于关于类的数据(元数据)调用其中定义的方法。您可以从一个类中获取一个实例,根据其名称获取一个方法,然后调用它。 - Fritz
@Gamb 10x,但是如果您修改源代码,那么您会生成一个新的源代码(正如维基百科所说),不是吗? - gran33
1
除非您不使用反射。例如,Hibernate使用cglib生成代码,通过操作字节码而不是源代码。 - Fritz
Java现在实际上有一个本地编译器API,可以在运行时随时调用。语言的静态性几乎与其构造加载能力无关。 - Esko
1个回答

4
我认为维基百科的解释并不太恰当。
反射(或内省)不是关于在运行时创建代码,而是关于代码在运行时能够自我反思(并根据此修改其行为)。例如,获取对象类型的信息(如C++中的RTTI)或获取与对象相关联的元数据(如Java中的注释)。
运行时代码生成与一等公民特性更相关,而不是反射,因此我认为当前的维基百科文章有些误导性。 更新 换句话说,对于这个问题的答案:
“好的,现在我的问题是,没有eval功能的静态语言(例如Java)如何进行反射?”
答案是反射不依赖于eval功能。这些是两个独立的语言特性。
正如Giulio Franco在评论中指出的那样 - Java能够进行运行时代码生成/操作(例如参见CGLIB)。

1
我想补充一下,Java类是在运行时加载的,并且有一个Java类可以让你即时编译和加载Java类。因此,实际上,Java 可以在运行时添加代码。也许你还可以删除、修改和重新加载一个类,但我认为这有一些限制(也许你不能卸载当前正在使用的类)。 - Giulio Franco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接