反射取含数组的构造函数时的参数类型传递

简介:

 

今天在和瑾华讨论ASM的时候,通过将反射的method转换为asm的method时遇到反射时数组的问题。当时两个人都卡住了,现在实验通了,顺手记录下来。

原始类:

 
  1. public class Person implements China { 
  2.     protected String name; 
  3.  
  4.     public Person(String name) { 
  5.         this.name = name; 
  6.     } 
  7.     public Person(String name1[],String name2) { 
  8.     } 
  9.  
  10.     public String sayHello(String name) { 
  11.         return "welcome " + name; 
  12.     } 
  13.  
  14.     protected void protect() { 
  15.         privatedMethod(); 
  16.     } 
  17.  
  18.     private void privatedMethod() { 
  19.  
  20.     } 
  21.  

通过反射取得构造函数, 通常的方法为:

 
  1. @Test 
  2.     public void test04() { 
  3.         try { 
  4.             Class<?> clazz = (Class<?>) Class 
  5.                     .forName("com.alibaba.demoeo.reflect.classes.Person"); 
  6.             Constructor<?>[] constructs = clazz.getConstructors(); 
  7.             for (Constructor<?> construct : constructs) { 
  8.                 System.out.println(construct.getName()); 
  9.             } 
  10.         } catch (Exception e) { 
  11.             e.printStackTrace(); 
  12.         } 
  13.     } 

如果要取得特定参数的构造函数,则为:

 
  1. @Test 
  2.     public void test07() { 
  3.         try { 
  4.             Class<?> clazz = (Class<?>) Class 
  5.             .forName("com.alibaba.demoeo.reflect.classes.Person"); 
  6.             Constructor<?> construct = clazz.getConstructor(String.class); 
  7.             System.out.println(construct); 
  8.         } catch (Exception e) { 
  9.             e.printStackTrace(); 
  10.         } 
  11.     } 

问题引出:而要取得含有数组的参数的构造函数如何办呢? 这也是我们卡住的原因,实验了clazz.getConstructor(String.class, String.class); clazz.getConstructor(Array.class, String.class);等都不行, 后来通过反射机制将参数类型输出进行查看,发现数组为:class [Ljava.lang.String;

 
  1. @Test 
  2. public void test05() { 
  3.     try { 
  4.         Class<?> clazz = (Class<?>) Class 
  5.         .forName("com.alibaba.demoeo.reflect.classes.Person"); 
  6.         Constructor<?>[] constructs = clazz.getConstructors(); 
  7.          
  8.         for (Constructor<?> construct : constructs) { 
  9.             Class<?>[] types = construct.getParameterTypes(); 
  10.             for(Class<?> type : types){ 
  11.                 System.out.println(type); 
  12.             } 
  13.             System.out.println("-------------"); 
  14.         } 
  15.     } catch (Exception e) { 
  16.         e.printStackTrace(); 
  17.     } 

输出为:

 
  1. class java.lang.String 
  2. ------------- 
  3. class [Ljava.lang.String; 
  4. class java.lang.String 
  5. ------------- 

好的,现在知道是什么内容了,那就使用这种类型来构造:

 
  1. @Test 
  2.     public void test06() { 
  3.         try { 
  4.             Class<?> clazz = (Class<?>) Class 
  5.             .forName("com.alibaba.demoeo.reflect.classes.Person"); 
  6.             Constructor<?> construct = clazz.getConstructor(Class.forName(("[Ljava.lang.String;")), String.class); 
  7.             System.out.println(construct); 
  8.         } catch (Exception e) { 
  9.             e.printStackTrace(); 
  10.         } 
  11.     } 

测试结果正确,输出如下:

 
  1. public com.alibaba.demoeo.reflect.classes.Person(java.lang.String[],java.lang.String) 

考虑getConstructor的参数为可变数组,于是考虑通过传递数组类型给getConstructor方法,经测试后通过,具体如下:

 
  1. @Test 
  2.     public void test08() { 
  3.         try { 
  4.             Class<?> clazz = (Class<?>) Class 
  5.             .forName("com.alibaba.demoeo.reflect.classes.Person"); 
  6.             Constructor<?> construct = clazz.getConstructor(new Class[]{String[].class,String.class}); 
  7.             System.out.println(construct); 
  8.         } catch (Exception e) { 
  9.             e.printStackTrace(); 
  10.         } 
  11.     } 

 

使用此方法测试ASM转换:

 
  1. public class Demo { 
  2.     public void test(String[] str){} 
  3.     /** 
  4.      * @param args 
  5.      */ 
  6.     public static void main(String[] args) throws Exception{ 
  7.         java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;")); 
  8.         //java.lang.reflect.Method method = Demo.class.getMethod("test", new Class[]{String[].class}); 
  9.          
  10.         com.alibaba.citrus.asm.commons.Method asmMethod = com.alibaba.citrus.asm.commons.Method.getMethod(method); 
  11.         System.out.println(asmMethod.getDescriptor()); 
  12.     } 

或者

 
  1. public class Demo { 
  2.     public void test(String[] str){} 
  3.     /** 
  4.      * @param args 
  5.      */ 
  6.     public static void main(String[] args) throws Exception{ 
  7.         //java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;")); 
  8.         java.lang.reflect.Method method = Demo.class.getMethod("test"new Class[]{String[].class}); 
  9.          
  10.         com.alibaba.citrus.asm.commons.Method asmMethod = com.alibaba.citrus.asm.commons.Method.getMethod(method); 
  11.         System.out.println(asmMethod.getDescriptor()); 
  12.     } 

测试结果:

 
  1. ([Ljava/lang/String;)V 

【注意】

1、今天讨论之后,也可以使用String[].class表达字符串数组也是可以的

 


本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/568119,如需转载请自行联系原作者

相关文章
|
6月前
通过反射获取方法返回的类型
通过反射获取方法返回的类型
|
5月前
|
Java
java反射-动态调用方法(无参无返回值、有参无返回值、有参有返回值)
java反射-动态调用方法(无参无返回值、有参无返回值、有参有返回值)
|
6月前
|
Java
【Java方法重载】 定义,使用,理解,示例解读
【Java方法重载】 定义,使用,理解,示例解读
149 0
|
Java
Java方法的重载、可变个数形参、方法参数的值传递机制
Java方法的重载、可变个数形参、方法参数的值传递机制
97 0
|
XML Java Maven
可以让反射获取到方法参数实际的变量名设置
可以让反射获取到方法参数实际的变量名设置
171 0
【构造函数】解析构造函数的作用
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。
116 0
|
C语言 C++
C++ 构造函数+析构函数+函数参数的传递
C++ 构造函数+析构函数+函数参数的传递
135 0
C++ 构造函数+析构函数+函数参数的传递
|
Java
JAVA反射时(getMethod),参数是数组怎么办?
JAVA反射时(getMethod),参数是数组怎么办?
177 0
下一篇
无影云桌面