Java 如何重新加载类以使注释可见?

Java 如何重新加载类以使注释可见?,java,classloader,Java,Classloader,在一个例子中,我知道为了真正确定某个注释是否存在于类中的某个地方,我需要用一个同时访问注释和类的类加载器重新加载它 现在,我正在为这样一个类加载器如何工作而挣扎。在我的设置中,我只是将注释作为一个java.lang.Class实例,并且可以使用该注释将类注释为一个java.lang.Class实例。这两个类都可能是由我不知道的不同类加载器加载的(类可能是远程加载的,所以它们不在本地文件系统上) 搜索时,我 /** *将多个类加载器合并为一个类加载器的类加载器。 *此类加载器加载的类与此类加载器相

在一个例子中,我知道为了真正确定某个注释是否存在于类中的某个地方,我需要用一个同时访问注释和类的类加载器重新加载它

现在,我正在为这样一个类加载器如何工作而挣扎。在我的设置中,我只是将注释作为一个
java.lang.Class
实例,并且可以使用该注释将类注释为一个
java.lang.Class
实例。这两个类都可能是由我不知道的不同类加载器加载的(类可能是远程加载的,所以它们不在本地文件系统上)

搜索时,我

/**
*将多个类加载器合并为一个类加载器的类加载器。
*此类加载器加载的类与此类加载器相关联, *例如,Class.getClassLoader()指向这个类加载器。 * *作者Christian d'Heureuse,Inventec Informatik AG,瑞士苏黎世,www.source-code.biz
*许可证:LGPL,http://www.gnu.org/licenses/lgpl.html
*如果您需要其他许可证,请联系作者。 */ 公共类JoinClassLoader扩展了ClassLoader{ 私有类加载器[]委托类加载器; 公共JoinClassLoader(ClassLoader父类、ClassLoader…DelegateClassLoader){ 超级(家长); this.delegateClassLoaders=delegateClassLoaders;} 受保护类findClass(字符串名称)引发ClassNotFoundException{ //调用DelegateClassLoader的loadClass()方法会更容易 //但是我们必须自己从字节码加载类,因为 //需要它与我们的类加载器相关联。 字符串路径=name.replace('.','/')+“.class”; URL=findResource(路径); 如果(url==null){ 抛出新的ClassNotFoundException(名称);} 字节缓冲字节码; 试一试{ 字节码=加载资源(url);} 捕获(IOE异常){ 抛出新的ClassNotFoundException(名称,e);} 返回defineClass(名称,字节码,null);} //省略了一些代码 }//结束类JoinClassLoader
所以我的问题是:

给定任意类
C
的类实例和可由任意类加载器加载的注释类
a
的类实例。
JoinClassLoader
按以下顺序实例化
C
A
的类加载器作为委托类加载器。调用
findClass
时,
JoinClassLoader
是否会重新加载类
C
,以便在实际使用注释
C
时注释
A
始终可见?如果不是的话,这样的类加载器实际上是什么样子的

在我早些时候问的一个问题中,我了解到这一点,以便真正 确保在类I中的某个地方存在或不存在某些注释 需要用一个类加载器重新加载它,该类加载器可以访问 注释和类

如果一个类已经被一个类加载器加载,而该类加载器可能无法访问所有注释,那么我可以相信这是真的。然而,我认为你得出了错误的结论

如果您希望能够在运行时反射分析类的注释,那么最好的解决方案是不重新加载它。相反,您应该确保它首先由一个类加载器加载,该类加载器还可以查看感兴趣的注释。(如果结果证明这还不够,那么我看不出重新加载有什么帮助。)

在任何情况下,重新加载该类都会得到一个不同的类(同名),即使其字节码与先前加载的版本的字节码相同。除了反射分析之外,使用它进行任何分析都很困难,而且很难确定这两个类实际上具有相同的字节码。重新加载当然不会用新加载的类替换现有的类。各种各样的乐趣接踵而至

/**
* 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