独自沉思寻找一类由它的简单名字(Finding a class reflectively by it

2019-07-03 13:19发布

我想知道是否有任何给定的功能,让我反思的一类,而无需编写其中类包含的软件包。

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

而不是这样做,我想为了有显示类的信息,只需键入类名。 就像这个“整型”

我怎样才能让我的程序只检查类名,不管它位于哪里?

Answer 1:

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;
  }
}

如果你想获得所有可用的软件包的列表,而不是硬编码他们, 在这里看到 。

警告说,这种方法是不太可能执行得非常好,所以应谨慎使用。



Answer 2:

这是不可能的,类被加载动态引用一次。 那么,有没有办法,因为没有这样的事情向下钻取可用包的列表。

然而,也有办法检查罐子,因为这些都是zip文件(包括标准JVM罐)。



Answer 3:

借来的代码,稍加修改(...从@罗迪的答案)

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


文章来源: Finding a class reflectively by its simple-name alone