如此有了如下研究:
/** * 利用JAVA反射机制调用ITelephony的endCall()结束通话。 */ private void endCall() { // 初始化iTelephony Class<TelephonyManager> c = TelephonyManager.class; Method getITelephonyMethod = null; try { // 获取所有public/private/protected/默认 // 方法的函数,如果只需要获取public方法,则可以调用getMethod. getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null); // 将要执行的方法对象设置是否进行访问检查,也就是说对于public/private/protected/默认 // 我们是否能够访问。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false // 则指示反射的对象应该实施 Java 语言访问检查。 getITelephonyMethod.setAccessible(true); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { ITelephony iTelephony = (ITelephony) getITelephonyMethod.invoke( tManager, (Object[]) null); try { iTelephony.endCall(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
下面的代码演示了如何利用安全性管理器与反射机制访问私有变量。
清单 3. 利用反射机制访问类的成员变量
// 获得指定变量的值 public static Object getValue(Object instance, String fieldName) throws IllegalAccessException, NoSuchFieldException ... { Field field = getField(instance.getClass(), fieldName); // 参数值为true,禁用访问控制检查 field.setAccessible( true ); return field.get(instance); } // 该方法实现根据变量名获得该变量的值 public static Field getField(Class thisClass, String fieldName) throws NoSuchFieldException ... { if (thisClass == null ) ... { throw new NoSuchFieldException( " Error field ! " ); } }其中 getField(instance.getClass(), fieldName) 通过反射机制获得对象属性,如果存在安全管理器,方法首先使用 this 和 Member.DECLARED 作为参数调用安全管理器的 checkMemberAccess 方法,这里的 this 是 this 类或者成员被确定的父类。 如果该类在包中,那么方法还使用包名作为参数调用安全管理器的 checkPackageAccess 方法。 每一次调用都可能导致 SecurityException。当访问被拒绝时,这两种调用方式都会产生 securityexception 异常 。
除访问私有变量,我们也可以通过这个方法访问私有方法。
清单 4. 利用反射机制访问类的成员方法 public static Method getMethod(Object instance, String methodName, Class[] classTypes) throws NoSuchMethodException ... { Method accessMethod = getMethod(instance.getClass(), methodName, classTypes); // 参数值为true,禁用访问控制检查 accessMethod.setAccessible( true ); return accessMethod; } private static Method getMethod(Class thisClass, String methodName, Class[] classTypes) throws NoSuchMethodException ... { if (thisClass == null ) ... { throw new NoSuchMethodException( " Error method ! " ); } try ... { return thisClass.getDeclaredMethod(methodName, classTypes); } catch (NoSuchMethodException e) ... { return getMethod(thisClass.getSuperclass(), methodName, classTypes); } }
// 调用含单个参数的方法 public static Object invokeMethod(Object instance, String methodName, Object arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException ... { Object[] args = new Object[ 1 ]; args[ 0 ] = arg; return invokeMethod(instance, methodName, args); } // 调用含多个参数的方法 public static Object invokeMethod(Object instance, String methodName, Object[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException ... { Class[] classTypes = null ; if (args != null ) ... { classTypes = new Class[args.length]; for ( int i = 0 ; i < args.length; i ++ ) ... { if (args[i] != null ) ... { classTypes[i] = args[i].getClass(); } } } return getMethod(instance, methodName, classTypes).invoke(instance, args); }