14

像 Dart 这样的一些语言使用基于镜像的反射,所以简单来说,这种实现与您在 C# 或 Java 中看到的传统反射之间有什么区别。

更新:我发现 Gilad Bracha 的这个优秀(而且有点古怪)的视频是关于 Newspeak 中基于镜子的反射。 http://www.hpi.uni-potsdam.de/hirschfeld/events/past/media/100105_Bracha_2010_LinguisticReflectionViaMirrors_HPI.mp4(镜像内容从 7:42 开始)

4

3 回答 3

23

对于许多用途,我认为镜像与 Java 反射没有什么不同。了解镜像最重要的一点是它们将反射 API 与标准对象 API 解耦,因此您使用反射 (obj) 代替 obj.getClass()。这是一个看似很小的差异,但它为您提供了一些好处:

  1. 对象 API 没有被污染,并且没有通过覆盖反射方法来破坏反射的危险。
  2. 您可能有不同的镜像系统。比如说,不允许访问私有方法。这最终可能对工具非常有用。
  3. 镜像系统不必包括在内。对于编译为 JS,这可能很重要。如果不使用镜像,则没有带外访问代码,修剪变得可行。
  4. 可以使镜像在远程代码上工作,而不仅仅是本地代码,因为您不需要反射对象与镜像位于相同的 Isolate 或 VM 中。

以下是在 Java 和 Javascript 中用于获取对象方法的镜像与反射的不同之处:

爪哇:

myObject.getClass().getMethods(); // returns an array

镖:

reflect(myObject).type.methods; // returns a map

Javascript:

var methods = [];
for (var m in myObject) {
  if (typeof m === 'function') {
    methods.push(m);
  }
}
于 2012-08-27T17:01:47.850 回答
5

您最好的选择是Dart 的联合设计师和规范作者Gilad Bracha 的这篇文章。为了一睹为快,阅读第一章可能就足够了。

摘要声称镜子遵循传统反射不遵循的三个必要原则:

我们确定了面向对象编程语言中反射和元编程设施的三个设计原则。 封装: 元级设施必须封装它们的实现。 分层:元级设施必须与基础级功能分开。 本体对应:元级设施的本体应该对应于它们操作的语言的本体。传统/主流反射架构不遵循这些规则。相比之下,围绕镜像概念构建的反射 API 的特点是遵守这三个原则。

于 2012-08-26T19:18:34.673 回答
1

我还要向您指出 Gilad 最近的另一个答案,他在其中列出了一些其他很好的参考资料:如何通过镜像 API 获取静态方法的具体对象?

于 2012-08-26T20:37:37.033 回答