Javaである程度の規模のプログラムを作成した場合、.classファイルを.jarファイルにアーカイブして使うことが多いと思います。Jakarta Commons等を使っている場合それらのj.jarファイルもクラスパスに置きますから、通常は複数の.jarファイル(と.jarに入れていない.classファイル)を使ってプログラムを実行します。
特にプログラムの開発中は、修正中のクラス以外は.jarのものを使うけれど修正中のクラスだけは.jarの外のものを使う、という状況が起き得ます。.javaファイルを一所懸命に修正していても、実は実行は.jarのクラスが使われてしまう、といった混乱の元になるので、あまりこうした事はやらないほうが良いのですが、やむをえない場合もあります。 そうした時に、実行中のクラスがどの.jarファイルに含まれているのかを知りたいと思うでしょう。
インスタンスの構造や機能はクラスによって決まりますが、そのクラスそのものの構造や機能を定義するクラス(メタクラス)が、Javaではjava.lang.Classというクラスとして提供されています。クラスの構造にアクセスするReflectionの機能なんかは、まさにこのClassを利用しています。このClassのオブジェクトには、そのクラスをロードしたクラスローダの情報や、そのクラスの出自の情報も入っていますので、これを使えば使用中のクラスがどのjarからやってきているのか知ることができます。
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
/**
* Classに関連するユーティリティクラス。
*/
public class ClassUtil {
/*
* ClassのCodeSourceのURLを返す。
* @param c 調査対象のClassオブジェクト。
* @return cのCodeSourceのURLまたはnull
*/
public static URL getCodeSourceURL(Class c) {
// ClassオブジェクトのProtectionDomainを取得
ProtectionDomain pd = c.getProtectionDomain();
if (pd == null) {
return null;
}
// そのCodeSourceを取得。
CodeSource cs = pd.getCodeSource();
if (cs == null) {
return null;
}
// CodeSourceのLocationを返す。
return cs.getLocation();
}
}
このClassUtil.getCodeSourceURL()メソッドを使えば、現在実行中のプログラム内で、targetという対象のオブジェクトがあった場合、ClassUtil.getCodeSourceURL(target.getClass());
を呼び出して、その戻り値を見ることで、targetオブジェクトのクラスがどこからロードされたのかを知ることができます。
ProtectionDomainやCodeSourceについてはJREのAPIのJavadocを読んでみてください。読んでもよく解らないかもしれませんが。