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

简介:

 

今天在和瑾华讨论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,如需转载请自行联系原作者

相关文章
|
域名解析 Java Maven
Maven 公共代理库
Maven 公共仓库提供了对 maven central、jcenter、google、spring 等常用的 Maven 仓库的镜像功能。用户可以通过页面浏览仓库内容、检索和下载制品。在构建时使用 Maven 个公共仓库地址下载制品速度更快,更稳定。
56248 1
Maven 公共代理库
|
监控 Java 测试技术
Java并发编程最佳实践:设计高性能的多线程系统
【4月更文挑战第6天】本文探讨了设计高性能Java多线程系统的关键原则和策略,包括理解并发基础、最小化共享状态、使用高级并发API、避免死锁、利用原子操作、优化锁策略、使用线程池以及监控和调优。遵循这些最佳实践可提升并发性能和可靠性,确保代码健壮性。同时,强调测试并发代码的重要性,以发现和解决潜在问题。
425 0
|
Android开发
Android关于Bitmap的缩放方法
最近要将图片传给服务器,但是服务器限制了图片的大小,所以我查询了许多相关文章,现在将其罗列出来。
1111 0
|
2天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
266 116
|
17天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
12天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
658 220
|
5天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
334 34
Meta SAM3开源:让图像分割,听懂你的话