8

クラスが含まれているパッケージを作成しなくても、クラスをイントロスペクトできる関数があるかどうか疑問に思いました。

たとえば、クラスIntegerのメソッドとスーパークラスを調べて、クラスが配置されているパッケージを指定する必要があります。これは「java.lang.Integer」になります

その代わりに、クラスの情報を表示するために、クラス名を入力するだけです。この「整数」のように

プログラムがどこにあるかに関係なく、クラス名をチェックするようにするにはどうすればよいですか?

4

3 に答える 3

14

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

ハードコーディングするのではなく、利用可能なすべてのパッケージのリストを取得する場合は、ここを参照してください

この方法はうまく機能しない可能性があることに注意してください。慎重に使用してください。

于 2012-11-04T06:04:24.813 に答える
1

借用したコード、わずかに変更(... @ 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;
}
于 2015-10-13T19:57:32.407 に答える
-1

それは不可能です。クラスは参照されると動的にロードされます。したがって、そのようなものがないため、利用可能なパッケージのリストをドリルダウンする方法はありません。

ただし、jarファイルはzipファイル(標準のJVM jarを含む)であるため、jarファイルを検査する方法があります。

于 2012-11-04T02:18:34.530 に答える