0

私はリフレクションと練習が初めてで、Web サイトからランダムな Java プロジェクトをダウンロードしました。どのクラスが main メソッドを持っているかを調べることにしたので、次のコードを書きました。

package reflection;
import java.io.IOException;
import java.lang.reflect.*;
import java.nio.file.*;

public class FindMethods {
    public static void main(String[] args) throws IOException{
        if(args.length==0){
            System.out.println("Exiting");
            System.exit(1);
        }else{
            Path p = Paths.get(args[0]);
            DirectoryStream<Path> allClassFiles = Files.newDirectoryStream(p, "*.class");
            for(Path each : allClassFiles){
//              System.out.println(each.getFileName());
                try {
                    findMethods(each.getFileName().toString());
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void findMethods(String file) throws ClassNotFoundException{
        System.out.println(file);
        Class c = Class.forName(file);
        Method[] m = c.getDeclaredMethods();
        for(Method each : m){
            System.out.println(each.toString());
        }
    }
}  

System.out.println(each.getFileName());.classフォルダー内のファイルを適切に返しますが、ClassNotFoundException のスタック トレースが散在しています。

クラスは次のとおりです。

Addwindow$1.class
Addwindow$2.class
Addwindow.class
Authorwindow.class
clsConnection.class
clsSettings$1.class
clsSettings.class
Deletewindow$1.class
Deletewindow$2.class
Deletewindow.class
Editwindow$1.class
Editwindow$2.class
Editwindow.class
Emprptwindow$PrintCommand.class
Emprptwindow.class
Helpwindow.class
LoginFrame$1.class
LoginFrame.class
MainMenu$1.class
MainMenu$2.class
MainMenu.class
Payrptwindow.class
printwindow$1.class
printwindow.class
Settingswindow$1.class
Settingswindow.class  

各クラスからメソッドを取得するには、コードにどのような変更を加える必要がありますか?

スタックトレース:

java.lang.ClassNotFoundException: Settingswindow
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at reflection.FindMethods.findMethods(FindMethods.java:33)
    at reflection.FindMethods.main(FindMethods.java:22)  

話題になっているランダムなプロジェクト:

http://projectseminar.org/java-projects/payroll-accounting-system/98/

4

3 に答える 3

1

.classはファイル名の一部ですが、クラス名の一部ではありません。に渡す前にストリップする必要がありますClass.forName

もう1つの問題はforName、ファイルシステムが使用するスラッシュやディレクトリ区切り文字ではなく、ピリオドを使用してパッケージを区切ることを想定していることです。すべてがデフォルトのパッケージに含まれている場合でも、これは問題にはなりません。

それでも機能しない場合は、クラスパスを再確認する必要があります。

于 2013-03-24T05:47:11.407 に答える
0

を含むクラス名は$、外部クラス内の匿名クラスです(の左側の名前によって決定されます$)。の検索では、これらを無視しても問題ありませんmain$メインループのクラス名にaが含まれているかどうかをテストし、処理をスキップするだけです。

あなたが見ているアプリについてもっと知らなければ、あなたのコードが他のクラス(のような)のいくつかを見つけることができない理由を私は言うことができませんclsConnection

于 2013-03-24T05:44:29.773 に答える
0

このアプローチには問題があります。プロジェクトのすべてのクラスをロードします。クラスをロードせずにクラスを分析することをお勧めします。そのためのツールがあります。http://www.jboss.org/javassistでできることは次のとおりです。

public static void findMethods(String file) throws Exception {
    ClassPool cp = ClassPool.getDefault();
    try (InputStream is = new FileInputStream(file)) {
        CtClass cc = cp.makeClass(is);
        for (CtMethod m : cc.getMethods()) {
            System.out.println(m);
        }
    }
}
于 2013-03-24T06:59:28.090 に答える