前几天做单元测试,需要验证类的private方法。要想在一个类中执行另外一个类的private方法,只有下面两种方法:
1.将private修改成public,不过这种会破坏类的封装;
2.使用反射,通过方法名来执行private方法。
一个简单的例子,如下:
public class MainClass { public static void main(String args[]){ Person p = new Person(); Class pClass = p.getClass(); String methodName = "getInfo"; Class[] parameterClass = new Class[]{int.class,String.class}; Object result = null; try { Method method = pClass.getDeclaredMethod(methodName, parameterClass); method.setAccessible(true); //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查 result = method.invoke(p, new Object[] { 35, "haha" }); } catch (Exception e) { e.printStackTrace(); } if(null != result){ String info = (String) result; System.out.println(info); } } } class Person{ private String getInfo(int age,String name){ return "name is: "+name +",age is: "+age; } }
但是,这样做会遇到一个问题。就是当你想通过反射执行从父类中继承的方法,会报异常 java.lang.NoSuchMethodException。
这是,可以通过getSuperclass来获取父类的类对象,然后继续执行,代码如下:
public class MainClass { public static void main(String args[]){ Father f = new Father(); Class fClass = f.getClass(); Class superClass = fClass.getSuperclass(); String methodName = "getInfo"; Class[] parameterClass = new Class[]{int.class,String.class}; Object result = null; try { Method method = superClass.getDeclaredMethod(methodName, parameterClass); method.setAccessible(true); //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查 result = method.invoke(f, new Object[] { 35, "haha" }); } catch (Exception e) { e.printStackTrace(); } if(null != result){ String info = (String) result; System.out.println(info); } } } class Person{ private String getInfo(int age,String name){ return "name is: "+name +",age is: "+age; } } class Father extends Person{ }
接下来,又产生了一个问题,有时候你并不想关心要执行的方法是不是从父类继续的。这时候,可以通过递归来得到Method对象。
public class MainClass { public static Method getMethod(Class classObj,String methodName,Class[] parameterClass){ Method method = null; try { method = classObj.getDeclaredMethod(methodName, parameterClass); } catch (NoSuchMethodException e) { method = getMethod(classObj.getSuperclass(),methodName,parameterClass); } return method; } public static void main(String args[]){ Father f = new Father(); Class fClass = f.getClass(); String methodName = "getInfo"; Class[] parameterClass = new Class[]{int.class,String.class}; Object result = null; try { Method method = getMethod(fClass,methodName,parameterClass); method.setAccessible(true); //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查 result = method.invoke(f, new Object[] { 35, "haha" }); } catch (Exception e) { e.printStackTrace(); } if(null != result){ String info = (String) result; System.out.println(info); } } } class Person{ private String getInfo(int age,String name){ return "name is: "+name +",age is: "+age; } } class Father extends Person{ }