質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

解決済

呼び出しクラス名をすべて取得したい

takuson
takuson

総合スコア29

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

2回答

0リアクション

1クリップ

363閲覧

投稿2022/08/09 07:43

編集2022/08/09 14:06

前提

ClassAの処理の初めから終わりまでに呼ばれたクラス名を取得したいと思い、
Threadからクラス名を取得してみたところ、こちらの想定と違う結果となりました。
私が求めている結果は、ClassAでClassXとClassYを呼び出していたらその2つのクラスが表示されることです。
しかし、得られた結果はClassAのみでした。
最終的にやりたいことは、これを利用してjarや複雑に継承等を行ってる場合に使用しているクラスを明確化したいです。

実現したいこと

・ClassA最初から最後までの処理で呼び出されたクラス名(できればメソッド名)を取得したい
・結果を表示させる処理はClassAで行う

試したソースコード

Java

package sample; public class ClassA { public static void main (String[] args) { ClassX.testMethod(); ClassY.testMethod(); printStackClass(); } private static void () { int count = Thread.currentThread().getStackTrace().length - 1; System.out.println("呼び出しクラスとメソッドを出力します"); for (int i = count; i > 1; i--) { System.out.println("クラス:" + Thread.currentThread().getStackTrace()[i].getClassName() + ", メソッド:" + Thread.currentThread().getStackTrace()[i].getMethodName()); } } }

得られた結果

呼び出しクラスとメソッドを出力します クラス:ClassA, メソッド:main

求めている結果

呼び出しクラスとメソッドを出力します クラス:ClassA, メソッド:main クラス:ClassX, メソッド:testMethod クラス:ClassY, メソッド:testMethod

補足情報(FW/ツールのバージョンなど)

・eclipse 4.4
・Java 1.8
・Windows10

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

jimbe

2022/08/09 10:48 編集

当然ですが、スタックトレースにはスタックに積まれている情報しかありません。スタックは呼び出しの深さで積まれるもので、過去に実行したモノが残っているわけではありません。 プログラムの実行過程にどのようなクラス・メソッドを経由してきたかの情報が java システムのどこかにあるという話は聞いたことはありません。 そのような情報があるということはどこかから得られているのでしょうか。
maisumakun

2022/08/09 10:53

> ClassAの処理の初めから終わりまでに呼ばれたクラス名を取得したいと思い 何のために取得したいのでしょうか。
takuson

2022/08/09 14:02

>jimbeさん スタックトレースから呼ばれたクラス名が取得できるということは、それを設定しているところを見つけられれば使用しているすべてのクラス名を取得できると思ったからです。 ただ、いまいちその部分が見えなかったので質問しました。 >maisumakunさん 質問の内容ではやりたいことをわかりやすく説明するためにこのような書き方になりましたが、最終的にはjarなどで固められて、処理が追いにくい部分を見るためです。(前提に追記しました) ちなみにデバックなどはできないためこのような形となりました。
jimbe

2022/08/09 15:20

> スタックトレースから呼ばれたクラス名が取得できるということは、それを設定しているところを見つけられれば使用しているすべてのクラス名を取得できると思った いえ、先に書きました通り、スタックにはその瞬間のデータしか入っていません。「スタック」の基本的な動作をお分かりであれば過去の情報が残っているとは考えられないと思います。 ClassX の testMethod を呼んだ時にスタックには戻るための情報が入りますが、戻った段階でその情報は無効/破棄になり、ClassY の testMethod を呼んだ時に上書きされてしまって ClassX の testMethod が実行されていたことは残らないはずです。 また、そもそもそのような履歴情報が残るのであれば、ある程度システムが稼働し続けるとやがてメモリを食い潰すことになり、その為の何かしらの対応(オプションで一定時間毎にファイルに書き出すとか)が必要になるように思いますが、そのような話も聞いたことがありません。(ログツール等では必ずあると思います。) 以上から、スタックトレースからは無理では無いでしょうか。 java バイナリコードを解析して依存関係を再構築して表示するようなレベルのツールが必要な気がします。そして、そのようなツールは探したことも無いので分かりません。スイマセン。
takuson

2022/08/10 00:53

>jimbeさん ご解説頂いた通り、ClassXを呼び出した後にClassYを呼び出した時点でClassXを呼び出したことはスタックトレースからなくなることは理解しています。 なので、最終的なスタックトレースからクラス名を取得するつもりはありません。(上記のソースコードのせいで混乱させてしまったのであればすみません) 今考えていることとしては、スタックトレースにスラス名を設定しているメソッドを探し、そのメソッドをオーバライドし、別途クラス名を格納するリストを用意する。 その後そのリストを直接表示させるか、ファイル出力するかは後々考えればいいと思っています。
jimbe

2022/08/10 03:16

スタックトレースにクラス名を設定しているメソッド・・・というものも無いのではないでしょうか。 スタックトレースのスタックは、アプリやライブラリレベルからは透過的に存在するものです。 java エンジン自体のコード ( は java では無いでしょう ) を見ればどこかしらにはスタックに入れている処理はあるはずですが、 java アプリから上書き出来るようなレベルでは無いはずです。 一時期良く聞いたアスペクト指向の紹介例として「既存のコードにログを仕込むのが簡単」というようなモノをよく見かけたように思います。 takuson さんの現状で使えるものか、機能として希望に添えるものか分かりませんが、 java にも AspectJ とかなんとかがあったと思いますので、そのような方向もご検討されては如何でしょうか。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。