本想等把反射技术看完再写篇文章总结下,但是刚看到Method类的时候,出了一点小差错,花了一点时间,解决了问题。虽然事后总结发现很简单的小问题,但是还是决定记录一下吧,毕竟好久没写博客了。
是这样的,我想通过反射技术获取String类的成员方法(以toLowerCase和charAt为例)。
步骤应该是这样的,首先获取String类的字节码对象,然后调用该对象的getMethod方法,返回Method对象,
再通过Method对象的invoke方法,调用Method所调用的底层的方法。具体实现如下:
private static void reflectMethod_2()throws Exception { String str1=new String("basketball"); Method method=String.class.getMethod("charAt",int.class);//获取charAt方法 System.out.println(method.invoke(str1, 1));//调用charAt方法,打印结果:a }
很容易就实现了。接下来我想获取toLowerCase方法,采用同样步骤,这里注意一个问题,toLowerCase方法的参数是空(null),没有对应的字节码对象,所以调用
Method |
getMethod(String name,Class<?>... parameterTypes) |
代码如下:
//使用反射技术获取String类中toLowerCase方法 private static void reflectMethod()throws Exception { String str1=new String("ABCDEFG"); Method method=String.class.getMethod("toLowerCase",(Class<?>)null); //获取toLowerCase() 方法 System.out.println(method.invoke(str1, (Object)null)); //invoke方法执行Method对象所调用的底层的方法,该方法的原型是 /* public Object invoke(Object obj,Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException*/ }
没想到运行时居然出错了。。。。。。。。。。。
错误提示如下:
java.lang.NoSuchMethodException: java.lang.String.toLowerCase(null)
at java.lang.Class.getMethod(Class.java:1622)
at reflectDemo.ReflectMethod.reflectMethod(ReflectMethod.java:35)
at reflectDemo.ReflectMethod.main(ReflectMethod.java:23)
居然抛出“没有该方法异常”。。。。
开始我还以为是函数名写错了,仔细看了一遍toLowerCase没错呀。。。
最后终于发现了问题,原来是强制转型出错了,这里不应该转成Class<?>,因为该方法的第二个参数是可变参数(...)的,内部封装的是数组,所以这里应该强制转成字节码类数组型Class<?>[],
同理,调用invoke方法,也应该将null转成Object[]型。代码如下:
private static void reflectMethod()throws Exception { String str1=new String("ABCDEFG"); Method method=String.class.getMethod("toLowerCase",(Class<?>[])null); //获取toLowerCase() 方法,这里因为该方法的参数是空,所以必须将null强制转为Class[]类型 System.out.println(method.invoke(str1, (Object[])null)); //invoke方法执行Method对象所调用的底层的方法,该方法的原型是 }
这样终于成功的打印出“abcdefg”了。
额,更正:
其实如果待反射的方法无参数,那就可以不写,所以正确的方式应该是这样:
private static void reflectMethod() throws Exception { String str1 = new String("ABCDEFG"); Method method = String.class.getMethod("toLowerCase"); System.out.println(method.invoke(str1)); }