相关疑难解决方法(0)

clojure类重装如何工作?

我一直在阅读代码和文档,试图了解类重新加载在clojure中的工作原理.根据许多网站,如http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html,每当你加载一个类本质上你获得字节码(通过任何数据机制),转换将字节码转换为类Class的实例(通过defineClass),然后通过resolveClass解析(链接)该类.(defineClass是否隐式调用resolveClass?).任何给定的类加载器只允许链接一次类.如果它试图链接现有的类,它什么都不做.这会产生问题,因为您无法链接新实例化的类,因此每次重新加载类时都必须创建类加载器的新实例.

回到clojure,我尝试检查加载类的路径.

在clojure中,您可以根据需要以多种方式定义新类:

匿名类:reify代理

命名类:deftype defrecord(在引擎盖下使用deftype)gen-class

最终,这些代码指向clojure/src/jvm/clojure/lang/DynamicClassLoader.java

其中DynamicClassLoader/defineClass使用super的defineClass创建一个实例,然后缓存该实例.当你想要检索类时,clojure加载调用forName调用类加载器和DynamicClassLoader/findClass,它首先在委托给超类之前查看缓存(这与大多数普通类加载器的工作方式相反,它们在哪里首先委托,而不是自己尝试.)混淆的重点如下:forName被记录为在返回之前链接类,但这意味着你不能从现有的DynamicClassLoader重新加载一个类,而是需要创建一个新的DynamicClassLoader但是我没有在代码中看到这一点.我理解代理和reify定义了匿名类,因此它们的名称不同,因此可以将其视为不同的类.但是,对于命名类,这会破坏.在真正的clojure代码中,您可以同时引用旧版本的类和对新版本类的引用,但尝试创建新类实例将是新版本.

请解释一下clojure如何在不创建DynamicClassLoader的新实例的情况下重新加载类,如果我能理解重新加载类的机制,我想将这个重新加载功能扩展到我可能使用javac创建的java .class文件.

注意:此问题涉及类RELOADING,而不仅仅是动态加载.重新加载意味着我已经实习了一个类,但想要实例化该实例的新更新版本.

我想重申一下,不清楚clojure如何能够重新加载deftype定义的类.调用deftype最终会调用clojure.lang.DynamicClassLoader/defineClass.再次执行此操作会导致再次调用defineClass,但手动执行此操作会导致链接错误.在这里发生了什么,允许clojure使用deftypes做到这一点?

clojure classloader

22
推荐指数
1
解决办法
3333
查看次数

标签 统计

classloader ×1

clojure ×1