2

我正在写我的硕士论文,其中涉及 .NET 中的 AOP 等,我提到在加载时不支持替换类是目前没有 .NET AOP 框架的一个重要因素。执行真正的动态编织——并非没有强加编织类必须在接口上扩展ContextBoundObjectMarshalByRefObject公开其所有语义的要求。

但是,您可以在 JVM 中使用 Java 执行此操作,这要归功于ClassFileTransformer

  • 你扩展ClassFileTransformer.
  • 您订阅了类加载事件。
  • 在类加载时,您重写类并替换它。

这一切都很好,但是我的项目主管在最后一刻要求我给他一份框架(和相关语言)的列表,这些框架(和相关语言)支持/不支持类替换。我现在真的没有时间去寻找这个:仅仅做一个肤浅的研究并可能在我的论文中加入错误的信息,我会感到不舒服。

所以我问你,哦,万能的编程社区,你能帮忙吗?当然,我不是要你自己研究这个。简单地说,如果您确定某个特定框架支持/不支持此功能,请将其作为答案。如果您不确定,请不要忘记指出。

非常感谢!


编辑:@ewernli

  • 我在问(2)。
  • 在 C# 中,您确实可以在运行时发出代码并动态创建新类,但它们是类,它们不会替换现有类。我想做的是在加载时转换类,就像你可以在 Java 中使用ClassFileTransformer.
  • 关于修改方法的签名:是的,你是对的。我应该提到,就我而言,我不想修改类的接口,而是修改其方法的内容。

你的回答真的很有帮助。谢谢 :)

4

4 回答 4

4

您是在询问 (1) 运行时真正的类替换,还是 (2) 在加载类时转换类的工具,或者 (3) 支持动态类加载的语言?

Java 支持动态类加载ClassLoader,转换ClassFileTransformer,但不支持真正的类替换。

我不确定 C#,但我认为您可以在运行时发出代码并动态创建新类,因此您可以实现 (3) 并且可能实现 (2)。

真正的类替换主要由动态语言支持,例如 Smalltalk、Ruby、我猜是 Python 和其他一些语言。这需要转换类的实例以匹配新形状。如果类发生变化,他们通常会将新字段初始化为 nil。

AFAIK,移植到 JVM 的动态语言对 ClassLoader 进行了广泛的黑客攻击,以支持运行时的类替换。对于 JRuby,请参阅第一次尝试调用动态以获取更多指针,了解他们现在如何做、有什么问题以及即将到来的invokedynamic可能会如何提供帮助。

由于类型系统的复杂性,这在静态类型语言中不提供。如果一个类中的方法签名发生变化,其他已经加载的现有类可能不需要遵守新的方法签名,这是不安全的。但是,在 java 中,只要使用Java Platform Debugger Architecture的签名相同,您就可以更改方法。

已经有人尝试将此功能添加到 Java 和/或静态类型语言中:

  • 对类型安全的动态 Java 类的运行时支持
  • 支持应用程序行为的意外动态适应
  • 一种Java软件动态更新技术

本文提供了相关问题的一般概述

  • 类型系统对动态软件演化的影响

不确定这是否能解决你最初的问题,但无论如何这些指针可能对你的论文很有趣。

于 2010-06-15T08:49:29.387 回答
2

Java语言不支持类文件替换。JVM 通过您提到的类公开该功能。因此,所有已移植到 JVM 的语言都可以利用它。

于 2010-06-15T08:18:03.747 回答
1

Erlang支持热代码交换,如果你也在寻找模拟动态类更新的理论框架,你可以看看Creol语言(解释)。

于 2010-06-15T09:12:46.717 回答
1

Objective-C 的运行时库支持类的动态构造和注册、惰性方法注册和“方法调配”,通过这种方法可以在运行时切换方法实现。以前的版本支持“Class swizzling”,通过它可以在运行时将一个类替换为另一个类,但现在使用方法 swizzling。这是参考文档。

于 2010-06-15T09:34:39.140 回答