Javaは様々なところで使われてきた実績があります。
だからこそ、様々な可能性が探られ、いろいろな機能が提供されてきました。
Javaで動的にクラスを作成する、という機能も、幾分前からあります。
Javaの良さは静的型付け言語でのお硬さですが、JVM上で動的にクラスを作成するとで、Javaの可能性が広まります。
広げ方は別途お伝えするとして、本稿ではJavassistを使ったJavaのクラスの動的生成をご紹介します。
クラスの動的生成とは
Javaはコンパイルを行う言語なので、普通は
ソースコード作成→コンパイルでクラスファイルを作成→アプリケーション実行
のようにアプリケーションを作っていきますが、クラスの動的生成を行うと、アプリケーションの実行中にクラスを作ることができます。
Javassistによるクラスの動的生成
クラスの動的生成を行うことのできるプロダクトはいくつかありますが、ここではjavassistを使用します。javassistはAPIがとてもうまく設計されており、わかりやすくクラスを作成することができます。
サンプル
サンプルの全体はGithubで公開してありますので、ここでは主要部分の抜粋を記載します。
//クラスの作成
CtClass cc = ClassPool.getDefault().makeClass("MyClass");
//フィールドの追加
CtField field = CtField.make("private int calledNumber = 0;", cc);
cc.addField(field);
//メソッドの追加
CtMethod method = CtNewMethod.make("public String generateCurrentString() {return \" + currentNumber is + \" + calledNumber++;}", cc);
cc.addMethod(method);
//アノテーションの追加
ConstPool constpool = cc.getClassFile().getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
Annotation annot = new Annotation("javax.xml.ws.BindingType", constpool);
annot.addMemberValue("value", new StringMemberValue("http://www.w3.org/2003/05/soap/bindings/HTTP/", constpool));
attr.addAnnotation(annot);
method.getMethodInfo().addAttribute(attr);
フィールドを追加するときも、メソッドを追加するときも、各インスタンスを生成してクラスに追加していく要領でできます。
簡単なのでぜひお試しください。
使いドコロがわからない?それはまた別稿でご紹介します。