今天在和瑾华讨论ASM的时候,通过将反射的method转换为asm的method时遇到反射时数组的问题。当时两个人都卡住了,现在实验通了,顺手记录下来。
原始类:
- public class Person implements China {
- protected String name;
- public Person(String name) {
- this.name = name;
- }
- public Person(String name1[],String name2) {
- }
- public String sayHello(String name) {
- return "welcome " + name;
- }
- protected void protect() {
- privatedMethod();
- }
- private void privatedMethod() {
- }
- }
通过反射取得构造函数, 通常的方法为:
- @Test
- public void test04() {
- try {
- Class<?> clazz = (Class<?>) Class
- .forName("com.alibaba.demoeo.reflect.classes.Person");
- Constructor<?>[] constructs = clazz.getConstructors();
- for (Constructor<?> construct : constructs) {
- System.out.println(construct.getName());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
如果要取得特定参数的构造函数,则为:
- @Test
- public void test07() {
- try {
- Class<?> clazz = (Class<?>) Class
- .forName("com.alibaba.demoeo.reflect.classes.Person");
- Constructor<?> construct = clazz.getConstructor(String.class);
- System.out.println(construct);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
问题引出:而要取得含有数组的参数的构造函数如何办呢? 这也是我们卡住的原因,实验了clazz.getConstructor(String.class, String.class); clazz.getConstructor(Array.class, String.class);等都不行, 后来通过反射机制将参数类型输出进行查看,发现数组为:class [Ljava.lang.String;
- @Test
- public void test05() {
- try {
- Class<?> clazz = (Class<?>) Class
- .forName("com.alibaba.demoeo.reflect.classes.Person");
- Constructor<?>[] constructs = clazz.getConstructors();
- for (Constructor<?> construct : constructs) {
- Class<?>[] types = construct.getParameterTypes();
- for(Class<?> type : types){
- System.out.println(type);
- }
- System.out.println("-------------");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
输出为:
- class java.lang.String
- -------------
- class [Ljava.lang.String;
- class java.lang.String
- -------------
好的,现在知道是什么内容了,那就使用这种类型来构造:
- @Test
- public void test06() {
- try {
- Class<?> clazz = (Class<?>) Class
- .forName("com.alibaba.demoeo.reflect.classes.Person");
- Constructor<?> construct = clazz.getConstructor(Class.forName(("[Ljava.lang.String;")), String.class);
- System.out.println(construct);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
测试结果正确,输出如下:
- public com.alibaba.demoeo.reflect.classes.Person(java.lang.String[],java.lang.String)
考虑getConstructor的参数为可变数组,于是考虑通过传递数组类型给getConstructor方法,经测试后通过,具体如下:
- @Test
- public void test08() {
- try {
- Class<?> clazz = (Class<?>) Class
- .forName("com.alibaba.demoeo.reflect.classes.Person");
- Constructor<?> construct = clazz.getConstructor(new Class[]{String[].class,String.class});
- System.out.println(construct);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
使用此方法测试ASM转换:
- public class Demo {
- public void test(String[] str){}
- /**
- * @param args
- */
- public static void main(String[] args) throws Exception{
- java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;"));
- //java.lang.reflect.Method method = Demo.class.getMethod("test", new Class[]{String[].class});
- com.alibaba.citrus.asm.commons.Method asmMethod = com.alibaba.citrus.asm.commons.Method.getMethod(method);
- System.out.println(asmMethod.getDescriptor());
- }
- }
或者
- public class Demo {
- public void test(String[] str){}
- /**
- * @param args
- */
- public static void main(String[] args) throws Exception{
- //java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;"));
- java.lang.reflect.Method method = Demo.class.getMethod("test", new Class[]{String[].class});
- com.alibaba.citrus.asm.commons.Method asmMethod = com.alibaba.citrus.asm.commons.Method.getMethod(method);
- System.out.println(asmMethod.getDescriptor());
- }
- }
测试结果:
- ([Ljava/lang/String;)V
【注意】
1、今天讨论之后,也可以使用String[].class表达字符串数组也是可以的
本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/568119,如需转载请自行联系原作者