クラス名から Class オブジェクトを取得
クラス名文字列から Class オブジェクトを取得する
前回の記事「Java オブジェクトに関連する Class オブジェクトの取得」では、具体例として Employee オブジェクトを作成して、それに関連する Class オブジェクトを取得しました。
今回は、明示的に Employee オブジェクトを作成せずに、クラスの名前だけから Class オブジェクトを取得します。
クラス名から Class オブジェクトを取得するには Class.forName() メソッドを利用します。 forName() メソッドは文字列でクラス名を受け取り、そのクラス名に対する Class オブジェクトを返します。
クラス名から Class オブジェクトを取得するサンプルコード
さっそく前回の記事で作ったコードを直し、Employee オブジェクトを作成することなく Class オブジェクトを取得してみましょう。
Employee クラスについては元の記事 「Java オブジェクトに関連する Class オブジェクトの取得」に記載しています。
今回は Employee オブジェクトを new で作成していません (9行目)。
package com.keicode.java.test;
import java.lang.reflect.Method;
public class TestApp {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c = Class.forName("com.keicode.java.test.Employee");
System.out.println("Class name: " + c.getName());
System.out.println("Methods:");
for (Method m : c.getMethods()) {
boolean isFirstParam = true;
System.out.print(" " + m.getName() + "(");
for (Class<?> p : m.getParameterTypes()) {
if (!isFirstParam) {
System.out.print(",");
}
System.out.print(p.getName());
isFirstParam = false;
}
System.out.println(")");
}
}
}
この実行結果は以前と同様に次のようになります。
Class name: com.keicode.java.test.Employee
Methods:
getFirstName()
getLastName()
wait(long)
wait(long,int)
wait()
equals(java.lang.Object)
toString()
hashCode()
getClass()
notify()
notifyAll()
ClassNotFoundException 例外の発生
Class.forName() メソッドは、上で見たようにクラス名を表す文字列から Class オブジェクトを取得します。
存在しないクラス名を渡すと、ClassNotFoundException 例外が発生します。
試しに存在しないクラス名 "XYZ" を渡すと、次のように ClassNotFoundException 例外が投げられ、 catch ブロックにて次のようなスタックトレースが出力されました。
Exception in thread "main" java.lang.ClassNotFoundException: XYZ
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
at com.keicode.java.test.TestApp.main(TestApp.java:9)
自分で書いたコードは一番下のフレーム (ReflectionTestApp3.java:8) の箇所だけですが、 Java の実行環境の内部動作の分も見えてくるのでスタックトレースは上記のように長くなります。
このため Class.forName() を呼ぶ時は ClassNotFoundException 例外を処理する try-catch ブロックまたは throws ClassNotFoundException のシグネチャが必要になります。