在question I asked earlier中我知道为了确实在某个类的某个地方存在或不存在某些注释,我需要使用可以同时访问两者的类加载器重新加载它 - 注释和类。
现在我正在努力解决这样一个类加载器的工作方式。在我的设置中,我只是将注释作为java.lang.Class
实例,并且可以使用该注释注释的类也作为java.lang.Class
实例。两者都可能由一些我不了解的不同类加载器加载(类可能是远程加载的,所以它们不在本地文件系统上)。
/**
* A class loader that combines multiple class loaders into one.<br>
* The classes loaded by this class loader are associated with this class loader,
* i.e. Class.getClassLoader() points to this class loader.
* <p>
* Author Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz<br>
* License: LGPL, http://www.gnu.org/licenses/lgpl.html<br>
* Please contact the author if you need another license.
*/
public class JoinClassLoader extends ClassLoader {
private ClassLoader[] delegateClassLoaders;
public JoinClassLoader (ClassLoader parent, ClassLoader... delegateClassLoaders) {
super (parent);
this.delegateClassLoaders = delegateClassLoaders; }
protected Class<?> findClass (String name) throws ClassNotFoundException {
// It would be easier to call the loadClass() methods of the delegateClassLoaders
// here, but we have to load the class from the byte code ourselves, because we
// need it to be associated with our class loader.
String path = name.replace('.', '/') + ".class";
URL url = findResource(path);
if (url == null) {
throw new ClassNotFoundException (name); }
ByteBuffer byteCode;
try {
byteCode = loadResource(url); }
catch (IOException e) {
throw new ClassNotFoundException (name, e); }
return defineClass(name, byteCode, null); }
// some code omitted
} // end class JoinClassLoader
所以我的问题是:
给定一个任意类C
的类实例和一个可由任意类加载器加载的注释类A
的类实例。使用JoinClassLoader
和C
的类加载器按顺序将A
实例化为委托类加载器。 JoinClassLoader
会在调用C
时重新加载课程findClass
,以便在A
实际注释时注释C
始终可见吗?如果不是这样的类加载器怎么样呢?
答案 0 :(得分:0)
在我之前提出的一个问题中,我知道这是为了真的 确保某些注释存在于某个类别中某个地方 需要使用可以访问两者的类加载器重新加载它 - 注释和课程。
鉴于已经由类加载器加载的类可能无法访问所有注释,我可以相信这是真的。不过,我认为你得出了错误的结论。
如果您希望能够在运行时反射分析类的注释,那么最好的解决方案就是不重新加载它。相反,您应确保由类加载器首先加载,该类加载器也可以查看感兴趣的注释。 (如果事实证明还不够,那么我看不出你怎么能指望重装来帮忙。)
在任何情况下,重新加载类会为您提供一个不同的类(同名),即使它的字节码与先前加载的版本相同。除了反射分析之外,将它用于任何事情都很棘手,并且很难确定实际上做的两个类具有相同的字节码。重新加载当然并不会用新加载的类替换现有的类。随之而来的是各种乐趣。