package com.snail.exam.javaexam; public final class SomeUtil { /** * デフォルトコンストラクタの無効化. */ private SomeUtil() { super(); } /** * x! を求めます. * @param x 数値 * @return x! */ public static int factorial(final int x) { return recursive(x); } /** * 再帰的に x * recursive(x-1) を実行します. * @param x 数値 * @return x! */ private static int recursive(final int x) { if (x == 1) { return x; } return x * recursive(x - 1); } }
package com.snail.exam.javaexam; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import org.junit.Test; import static org.junit.Assert.assertEquals; public class SomeUtilTest { @Test public void testFactorial() { // 普通のテスト assertEquals(1, SomeUtil.factorial(1)); assertEquals(120, SomeUtil.factorial(5)); } @Test public void testPublicMethod() throws Exception { Method method = SomeUtil.class.getMethod("factorial", int.class); assertEquals(1, method.invoke(null, 1)); assertEquals(120, method.invoke(null, 5)); } @Test public void testPrivateMethod() throws Exception { // Private な Constructor を呼び出す Class clazz = Class.forName("com.snail.exam.javaexam.SomeUtil"); Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); Object obj = constructor.newInstance(); // Private な recursive() メソッドを呼び出す Method method = clazz.getDeclaredMethod("recursive", int.class); method.setAccessible(true); assertEquals(1, method.invoke(obj, 1)); assertEquals(120, method.invoke(obj, 5)); } }
Class clazz = Class.forName("com.snail.exam.javaexam.SomeBean"); Constructor constructor = clazz.getConstructor(); Object obj = constructor.newInstance();
引数があるコンストラクタを指定する場合は、getConstructor() で、引数クラスを指定する
Class clazz = Class.forName("com.snail.exam.javaexam.SomeBean"); Constructor constructor = clazz.getConstructor(String.class, int.class); Object obj = constructor.newInstance();
Class clazz = Class.forName("com.snail.exam.javaexam.SomeUtil"); Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); Object obj = constructor.newInstance();
getDeclaredConstructor?() は、Private コンストラクタも指定できる。
setAccessible(true); でアクセスできるようにしてから newInstance()
SomeBean bean = new SomeBean(); Method method = SomeBean.class.getMethod("getChild", int.class); assertEquals("Taro", method.invoke(bean, 1));
Method method = SomeUtil.class.getMethod("factorial", int.class); assertEquals(1, method.invoke(null, 1)); assertEquals(120, method.invoke(null, 5));
method.invoke() の第一引数に null を指定する
Method method = clazz.getDeclaredMethod("recursive", int.class); method.setAccessible(true); assertEquals(1, method.invoke(obj, 1)); assertEquals(120, method.invoke(obj, 5));
getDeclaredConstructor?() は、Private メソッドも指定できる。
setAccessible(true); でアクセスできるようにしてから invoke()
public class RectUtil { public static int calcArea(XY[] points){ int area = 0; for(int cnt = 0; cnt < points.length ; cnt++) { XY p = points[cnt]; XY q = (cnt + 1 == points.length) ? points[0] : points[cnt+1]; area += (p.getX() - q.getX()) * (p.getY() + q.getY()); } return area / 2; } }
Method method = RectUtil.class.getDeclaredMethod("calcArea", new Class<?>[]{XY[].class}); System.out.println( method.invoke(null, new Object[]{new XY[]{new XY(1,1), new XY(3,1),new XY(3,3),new XY(1,3)}}));