Java Reflection: Call by Name Singleton Class
Call by nameでクラスを呼ぶのは,Javaでは簡単
Class<? extend Parent> clazz = Class.forName(className); clazz.newInstance()
しかし,classNameがシングルトンだったらどうなるかというと,
普通シングルトンのコンストラクタはprivateなのでException発生.
ではどうするかというと,DeclaredConstructorを持ってきて,
setAccessible(true)にする.
しかし,この方法はSecuritManagerに制限がかかっていると使えない.
そこで,MethodInvocationする.
それぞれの例下記に示す.
クラス一覧
SampleApp
Model.java
package edu.kzk.java_samle.reflection; public interface Model { public void execute(); }
ModelBase.java
package edu.kzk.java_samle.reflection; public class ModelBase implements Model { protected static ModelBase instance; protected ModelBase(){}; public void execute() {System.out.println("Execute!");}; }
ModelImpl.java
package edu.kzk.java_samle.reflection; public class ModelImpl extends ModelBase { protected ModelImpl(){}; public static ModelBase getInstance() { if (instance == null) { instance = new ModelImpl(); } return instance; } @Override public void execute() { super.execute(); } }
CreateObjectByNewInstanceMethodSample.java
package edu.kzk.java_samle.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class CreateObjectByNewInstanceMethodSample { public static void main(String[] args) { // class String className = "edu.kzk.java_samle.reflection.ModelImpl"; try { Class<? extends ModelBase> clazz = (Class<? extends ModelBase>) Class.forName(className); // new ModelBase model = (ModelBase) clazz.newInstance(); model.execute(); } catch (ClassNotFoundException | SecurityException | IllegalAccessException | IllegalArgumentException | InstantiationException e) { e.printStackTrace(); } } }
CreateSingletonByDeclaredConstructorSample.java
package edu.kzk.java_samle.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class CreateSingletonByDeclaredConstructorSample { public static void main(String[] args) { // class String className = "edu.kzk.java_samle.reflection.ModelImpl"; try { Class<? extends ModelBase> clazz = (Class<? extends ModelBase>) Class.forName(className); // constructor Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); ModelBase model = (ModelBase) constructor.newInstance(); model.execute(); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { e.printStackTrace(); } } }
CreateSingletonByMethodReflectionSample.java
package edu.kzk.java_samle.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class CreateSingletonByMethodReflectionSample { public static void main(String[] args) { // class String modelName = "edu.kzk.java_samle.reflection.ModelImpl"; try { Class<? extends ModelBase> clazz = (Class<? extends ModelBase>) Class.forName(modelName); // show methods Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method.toString()); } System.out.println(""); // invoke method Method method = clazz.getMethod("getInstance"); ModelBase model = (ModelBase) method.invoke(null); model.execute(); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } }