在JVM运行时查找类

时间:2012-02-03 06:46:35

标签: java classloader

有没有找到使用类加载器信息扩展特定类的所有类名?

更详细的说明

我有一个jar文件,其中有3个类Xextends A),Yextends A)和Zextends B) 。我已将此jar文件放入类路径并启动JVM(调用某些类的main方法)。现在从这个main方法有没有办法找到属于A的子类的类?即班级XY,因为他们正在扩展班级A

2 个答案:

答案 0 :(得分:0)

不幸的是,没有简单的方法可以做到这一点。在由类加载器加载之前,JVM没有关于特定类的信息。但是要让类加载器实际加载类,您必须知道类的名称。鸡肉和鸡蛋问题。

然而,还有其他一些,但有点复杂的方式。

  1. 要在运行应用程序时确定类路径中有哪些.jar文件,可以调用System.getProperty("java.class.path"),然后沿File.separatorChar个字符拆分类路径条目。类路径条目可能很多,考虑以某种方式过滤它们(仅限于特定目录,不包括rt.jar等标准条目。)
  2. 如果您知道哪个.jar文件包含您感兴趣的类,则可以使用类JarFile的实例打开它。然后,您可以迭代所有条目(例如。.class文件),并从JAR文件中的内部路径构建其完全限定的类名。
  3. 使用手中的类名,可以调用Class.forName()来加载类,并且可以使用反射来获取每个类的超类,以确定它是否扩展了您的特定类。
  4. 请注意,此方法非常耗费资源,您可以使JVM实际加载.jar文件(或多个.jar文件)中的所有类,即使您不能使用他们以后。这浪费了相当多的记忆(PermGen空间)。

    有一些低级库可以处理Java字节码和类文件(请参阅BCELASM)。使用它们,您将能够确定一个类的超类而不实际(类)加载它,因此这种方式更快,使用更少的内存。

    您的问题类似于JavaEE应用程序服务器在部署Web应用程序时的工作方式。要找出要加载和初始化的类,例如HTTP servlet,它们必须检查Web存档中的所有类,以查找特定的Java注释或超类。但是,他们至少知道要扫描哪个.war文件。例如,Apache Tomcat使用BCEL而不是Java类加载机制。

    如果您正在为您的应用程序设计某种动态类加载机制,那么请考虑其他设计选项来缩小加载程序必须扫描的类的数量,以找到要加载的正确类:详细说明使用JAR中的一些元信息(您可以使用前面提到的.jar来读取JarFile文件中的条目)来指定要查找的类,而不是将其放在类路径上META-INF/manifest.mf等等。

答案 1 :(得分:0)

只是为了完整起见 http://code.google.com/p/reflections/

链接帖子中提到的其他人