通过反射机制创建一个构造方法中参数数量可变的对象
来源:互联网 发布:录屏大师windows 编辑:程序博客网 时间:2024/05/24 03:38
自学的时候刚看到Class类与Java反射,才开始讲解了Class类得到对应类构造方法的方法。
我们可以用getConstructors()等四个方法得到需要的Constructor构造方法或者其数组,然后再利用Constructor的newInstance方法进行创建对象。
但是我尝试了很多次,都无法直接取到构造方法参数数量可变的Constructor对象,只能直接得到参数数量固定的Constructor,而想要取到前者,则暂时以我自身的知识掌握需要采取其他的方式。
首先创建一个含有需要的构造方法的类A
public class A {//这是一个实验类,含有无参构造方法和三个有参构造方法//其中两个有参构造方法的参数数量可变public A(){System.out.println("无参构造方法");}public A(int i){System.out.println("有参构造方法,参数为一个int");System.out.println("该int值为:"+i);}public A(int...arr){System.out.println("有参构造方法,参数为一个int类型的数组");if (arr.length==0){System.out.println("该数组的容量为0");}else{System.out.print("该数组的值分别为:"+arr[0]);for (int i=1;i<arr.length;i++){System.out.print("-"+arr[i]);}System.out.println();}}public A(String...arr){System.out.println("有参构造方法,参数为一个String类型的数组");if (arr.length==0){System.out.println("该数组的容量为0");}else{System.out.print("该数组的值分别为:"+arr[0]);for (int i=1;i<arr.length;i++){System.out.print("-"+arr[i]);}System.out.println();}}}对应的我在TestA测试类里写了六个方法用于测试和学习
方法一是测试无参构造方法是否能成功创建对象。
public static void getNull(){System.out.println("---getNull---");Class class1=A.class;try{Constructor<A> constructor=class1.getConstructor(null);A a=constructor.newInstance(null);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getNull---无参构造方法方法二和三是测试getConstructor方法的参数必须是数组还是单个,虽然参数形式是一个可变长度数组的形式。[i=1]
public static void getInt1(int i){System.out.println("---getInt1---");Class class1=A.class;try{//错误方式:参数是int,则必须用int.calss;参数是Integer才能用Integer.class//Constructor<A> constructor=class1.getConstructor(Integer.class);Constructor<A> constructor=class1.getConstructor(int.class);A a=constructor.newInstance(i);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInt1---有参构造方法,参数为一个int该int值为:1
public static void getInt2(int i){System.out.println("---getInt2---");Class class1=A.class;try{Class[] classs=new Class[]{int.class};Constructor<A> constructor=class1.getConstructor(classs);A a=constructor.newInstance(i);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInt2---有参构造方法,参数为一个int该int值为:1方法四是给getConstructor的参数为一个固定长度的Class数组,由三个int.class组成。
[arr={1,2,3}]
public static void getInts1(int...arr){System.out.println("---getInts1---");Class class1=A.class;try{Class[] classs=new Class[]{int.class,int.class,int.class};Constructor<A> constructor=class1.getConstructor(classs);A a=constructor.newInstance(arr);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInts1---错误类型为java.lang.NoSuchMethodException说明以固定长度的class数组作为参数是得不到我们想要的Constructor对象的。
方法五尝试性地用了一下可能能得到class不确定长度数组的方式,并将其作为参数。[arr={1,2,3}]
public static void getInts2(int...arr){System.out.println("---getInts2---");Class class1=A.class;try{Constructor<A> constructor=class1.getConstructor(int.class.getClasses());A a=constructor.newInstance(arr);/*System.out.println(constructor);A a=constructor.newInstance(null);*/}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInts2---错误类型为java.lang.IllegalArgumentException输出结果2:(将“A a=constructor.newInstance(arr);”注释并且将原本注释的释放出来)---getInts2---public com.A()无参构造方法第一个输出结果的错误类型是参数不匹配,也就是说得到的Constructor方法的参数不匹配arr,通过第二个输出结果我们得到结论,这种方式得到的实际上是类的无参构造方法。
方法五是目前我可以想到的能得到一个参数数量可变的构造方法的方式,利用了Constructor类的isVarArgs()方法,该方法判定一个Constructor对象的参数列表是否是可变的,为了测试我又给A类加上了参数为String...arr的构造方法用于区分。
public static void getInts3(int...arr){System.out.println("---getInts3---");Class class1=A.class;try{Constructor<A>[] constructors=class1.getConstructors();for (int i=0;i<constructors.length;i++){System.out.println((i+1)+":"+constructors[i]);System.out.println("该方法的参数数量可变:"+constructors[i].isVarArgs());if (constructors[i].isVarArgs()){try{A a=constructors[i].newInstance(arr);}catch(Exception e2){System.out.println("该方法无法以int[]作为参数创建对象");System.out.println("错误类型为"+e2.getClass().getName());}}}}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInts3---1:public com.A(java.lang.String[])该方法的参数数量可变:true该方法无法以int[]作为参数创建对象错误类型为java.lang.IllegalArgumentException2:public com.A(int[])该方法的参数数量可变:true有参构造方法,参数为一个int类型的数组该数组的值分别为:1-2-33:public com.A(int)该方法的参数数量可变:false4:public com.A()该方法的参数数量可变:false成功得到了需要的构造方法,并且用它创建了一个对象。
虽然成功得到了,但是还是觉得应该有某一种方式可以直接得到符合参数要求的单个Constructor对象的方式,而不是在类所有的构造方法中挨个去判定。
= =所以还是有一点纠结,如果在后面的学习中发现了新的方式会补充上来的= =
=================分===============割=================线=======================
找到方法了!!!!找到了妈个鸡!!!!
我们将第四个方法改一下![arr={1,2,3}]
public static void getInts2(int...arr){System.out.println("---getInts2---");Class class1=A.class;try{Constructor<A> constructor=class1.getConstructor((new int[0]).getClass());A a=constructor.newInstance(arr);/*System.out.println(constructor);A a=constructor.newInstance(null);*/}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getInts2---有参构造方法,参数为一个int类型的数组该数组的值分别为:1-2-3似乎看上去应该是一个数组对象然后调用getClass方法,而不是一个单个的对象调用getClass。
所以我觉得需要继续尝试一下!
现在要对A类的String那个构造方法进行尝试![arr={"str1","str2","str3"}]
public static void getStrs1(String...arr){System.out.println("---getStrs1---");Class class1=A.class;try{Constructor<A> constructor=class1.getConstructor((new String[0]).getClass());System.out.println(constructor);A a=constructor.newInstance(arr);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getStrs1---public com.A(java.lang.String[])错误类型为java.lang.IllegalArgumentException很绝望= =参数不匹配,但是明明Constructor对象已经取正确了啊,参数的确是String的可变长度数组啊!
于是我又修改了一下= =
public static void getStrs1(String...arr){System.out.println("---getStrs1---");Class class1=A.class;try{Constructor<A> constructor=class1.getConstructor((new String[0]).getClass());Class[] fields=constructor.getParameterTypes();System.out.println("参数列表长度为:"+fields.length);for (int i=0;i<fields.length;i++){System.out.println((i+1)+"参数类型为:"+fields[i].getName());}System.out.println("参数arr的类型为:"+arr.getClass().getName());System.out.println(constructor);A a=constructor.newInstance(arr);}catch(Exception e){System.out.println("错误类型为"+e.getClass().getName());}}输出结果:---getStrs1---参数列表长度为:11参数类型为:[Ljava.lang.String;参数arr的类型为:[Ljava.lang.String;public com.A(java.lang.String[])错误类型为java.lang.IllegalArgumentException所以我也不知道说什么好= =明明类型都是[Ljava.lang.String;,但是就是类型不匹配,心好累= =
等知道为什么了再继续写吧= =
- 通过反射机制创建一个构造方法中参数数量可变的对象
- java中参数数量可变的方法
- PHP通过反射机制调用可变参数方法
- 通过反射创建对象(有参数和无参数构造方法)
- 通过反射可以获取Class的构造方法 通过构造方法创建对象
- java中利用反射机制得到一个类的所有构造方法,成员方法机器参数的列表
- 反射机制学习2(构造方法创建对象)
- 5.5 参数数量可变的方法
- java参数数量可变的方法
- Java :参数数量可变的方法
- 通过Java反射机制构造类的对象
- JSP中通过反射机制创建javaBean对象
- 利用反射调用带参数的构造函数创建对象
- 反射机制的概述和字节码对象的获取,通过反射获取构造方法并使用;通过反射获取成员变量并使用;通过反射获取私有成员变量并使用;通过反射获取成员方法并使用
- Java中通过反射获取类的信息(方法名,参数,构造函数等)
- [IOS 开发] OC 定义一个方法,参数数量可变.
- 对象包装器与自动(拆箱)装箱+参数数量可变的方法+枚举类
- Java通过反射机制使用非默认构造器创建对象
- Okhttp源码阅读之旅(二)
- 转行穷三年?未必!
- C#语言基础学习总结-1
- vue-express-mogodb_SPA 使用 js 搞定前后端。
- YJKJpromise
- 通过反射机制创建一个构造方法中参数数量可变的对象
- 2016蓝桥杯C/C++省赛 方格填数(深搜DFS)
- ECDH 秘钥交换
- 【Android】as开发环境搭建
- macbook下启动mysql报错 . ERROR! The server quit without updating PID file
- 2017.3.13-2017.3.19 第三个星期
- Java 指定线程执行顺序(三种方式)
- 卷积网络层计算
- MIT的《深度学习》精读(4)