仅通过简单的名称反思地找到一个类

时间:2012-11-04 02:08:59

标签: java class reflection

我想知道是否有任何给定的函数允许我内省一个类而不必编写包含类的包。

例如,我想看看类 Integer 的方法和超类,为了做到这一点,我必须指定类所在的包。这将是“java.lang.Integer”

我没有这样做,而是只想输入类名,以便显示类的信息。就像这个“整数”

如何让我的程序只检查班级名称,无论它位于何处?

3 个答案:

答案 0 :(得分:9)

Java不会阻止您创建自己的my.company.Integer类和my.other.company.Integer类,因此它无法知道哪个Integer类是正确类。

我建议的答案是关闭的事情是创建一个预定义的包列表,您要在其中搜索类,并继续尝试每个包直到找到您的类。

类似于:

class ClassFinder{
  public static final String[] searchPackages = {
    "java.lang",
    "java.util",
    "my.company",
    "my.company.other" };

  public Class<?> findClassByName(String name) {
    for(int i=0; i<searchPackages.length; i++){
      try{
        return Class.forName(searchPackages[i] + "." + name);
      } catch (ClassNotFoundException e){
        //not in this package, try another
      } catch (...){
        //deal with other problems...
      }
    }
    //nothing found: return null or throw ClassNotFoundException
    return null;
  }
}

如果您想获取所有可用软件包的列表而不是硬编码,see here

请注意,此方法不太可能表现良好,因此请谨慎使用。

答案 1 :(得分:0)

这是不可能的,一旦引用,动态加载类。因此,没有办法深入挖掘可用包的列表,因为没有这样的东西。

但是,有一些方法可以检查罐子,因为它们是zip文件(包括标准的JVM罐子)。

答案 2 :(得分:0)

借用代码,稍加修改(......来自@ rodion的答案)

/**
 * Returns first loaded Class found in the searchPackages
 * @param classname the simple class name (e.g. "String")
 * @param searchPackages String[] of packages to search.
 *                       <li>Place the more important packages at the top since the first Class
 *                           found is returned</li>
 *                       <code>//Example
 *                        public static final String[] searchPackages = {
 *                          "java.lang",
 *                          "java.util",
 *                          "my.company",
 *                          "my.company.other" };
 *                       </code>
 * @return the loaded Class or null if not found
 */
public static final Class<?> findClassByName(String classname, String[] searchPackages) {
    for(int i=0; i<searchPackages.length; i++){
        try{
            return Class.forName(searchPackages[i] + "." + classname);
        } catch (ClassNotFoundException e){
            //not in this package, try another
        }
    }
    //nothing found: return null or throw ClassNotFoundException
    return null;
}

修改相同的代码,以便在找到重复的类名称时抛出异常

/**
 * Returns the loaded Class found in the searchPackages
 * @param classname the simple class name (e.g. "String")
 * @param searchPackages String[] of packages to search.
 *                       <li>Place the more important packages at the top since the first Class
 *                           found is returned</li>
 *                       <code>//Example
 *                        public static final String[] searchPackages = {
 *                        "java.lang",
 *                        "java.util",
 *                        "my.company",
 *                        "my.company.other" };
 *                       </code>
 * @throws RuntimeException if more than one class of the same classname found in multiple packages
 * @return the loaded Class (guaranteed to be unique among the searchPackages) or null if not found
 */
public static final Class<?> findClassByNameNoDupes(String classname, String[] searchPackages) {

    Class<?> foundClass = null;
    for(int i=0; i<searchPackages.length; i++){
        try{
            boolean wasNull = foundClass == null;
            foundClass = Class.forName(searchPackages[i] + "." + classname);
            if (!wasNull) throw new RuntimeException(classname + " exists in multiple packages!");
        } catch (ClassNotFoundException e){
            //not in this package, try another
        }
    }
    return foundClass;
}