Fileクラスで得たjavaファイル中にあるメソッド一覧の取得方法
Fileクラスで得たjavaファイル中にあるメソッド一覧の取得方法
私は今、javaで、ファイルチューザにより、javaファイルを読み込んで、その選択したjavaファイル中にあるメソッドの一覧を取得したいのですが、よくわからないので、方法を教えてください。
私は今、javaで、ファイルチューザにより、javaファイルを読み込んで、その選択したjavaファイル中にあるメソッドの一覧を取得したいのですが、よくわからないので、方法を教えてください。
@javaboy
Class.forNameはclassファイル(拡張子が.classのファイル)を読み込む処理ですので、質問者様が言っているjavaファイルを読み込むという要件には合致しないかと思います。
※Class.forNameが動くにはClassLoaderによってclassファイルもしくはjarファイルがjvm上に読み込まれている必要があります。
@ponch
「JavaParserの使い方がわからないから他の手段を検討する」ということ自体に問題はありませんが、質問内容からしてもJavaParserが一番の近道かと思われます。
具体的にどの使い方がわからないのでしょうか。
https://qiita.com/opengl-8080/items/50ddee7d635c7baee0ab
こちらの記事はとても詳しく記載されていますので、質問者様が求めている情報は取得できるかと思いおます。
こちらの記事ではJavaParserを使うためにGradleを使用しているので、Gradleの使い方から調べてみてはどうでしょうか。
もしJavaParserを使わない場合は、以下のような方法が考えられます。
①javaファイルをコンパイルしたのち、「javap」コマンドもしくは「jad」コマンドを使用して、解析する(javaファイルをコンパイルできる場合に限ります。)
②javaの文法に沿った正規表現などを作成し、地道に調べる。これについては車輪の再発明ですのであまりおすすめできません。
@ponch
Questioner
すみません。入力ミスです。修正しました↓また、ファイルチューザとは違うかもしれませんが
File file = ...
Path directory = Path.of(file.toURI());
try {
for (Path path:Files.newDirectoryStream(directory) {
File file2 = path.toFile();// file2はfileの中に入っているファイル
}
}catch (IOException e) {
e.printStackTrace();
}
@ponch
Questioner
すみません。タイトルをしっかり読んでなくてフォルダの中のファイル一覧を取得したいのかと誤って認識してしまいました。そんな時はリフレクションを使ってはいかがでしょうか。
public class Main{
public static void main(String[] args) {}
et<String> methodNameList = new HashSet<>;//メソッドの名前一覧
try {
Class<?> stringClass = Class<?>.forName(args[0]);//コマンドライン引数にしていされたクラスを取得
Method[] methods = stringClass.getMethods();// メソッド一覧を取得
for (Method method : methods) {
methodNameList.add(method.getName());// methodNameListにメソッド名を追加
}
} catch (ClassNotFoundException e) {
// java.lang.Stringが存在しなかった場合
} catch (SecurityException e) {
// メソッド一覧を取得できなかった場合
}
methodNameList.stream().forEach(System.out::println); // メソッド一覧を表示
}
}
これがリフレクションです。しかし、リフレクションは処理を遅くするため注意してください。
@ponch
Questioner
未検証ですがJavaParserというものが使えないでしょうか?
https://github.com/javaparser/javaparser
https://qiita.com/opengl-8080/items/50ddee7d635c7baee0ab
@ponch
Questioner
これではだめでしょうか。クラスパスが入っている前提の話になりますが、
public class Main {
public static void main(String[] args) throws ClassNotFoundException{
Class<?> classInstance = Class<?>.forName(args[0]);
// リフレクション処理
}
}
java Main java.lang.String
Path file = ...
String packageName = Files.lines(file).fillter(s -> s.matches("^package .*")).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).substring(8);
packageName = packageName.substring(0, packageName.length() - 1);
Class<?> classInstance = Class<?>.forName(packageName + "." + file.getFileName());
// リフレクション処理
未検証ですので、エラーなどあれば、教えてください
@ponch
Questioner
修正しました。
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
public class Main {
public static void main(String[] args) throws Exception{
Path file = Paths.get("Main.java");
String packageName = "";
try {
packageName = Files.lines(file).filter(s -> s.matches("^package .*")).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).substring(8);
packageName = packageName.substring(0, packageName.length() - 1);
} catch (StringIndexOutOfBoundsException e) {}
Class<?> classInstance = Class.forName(packageName + (packageName == "" ? "" : ".") + file.getFileName().toString().substring(0, file.getFileName().toString().length() - 5));
// リフレクション処理
}
}