关于通过反射调用构造函数创建对象失败的问题

jack54877012 2017-11-20 05:15:20
代码如下,通过反射用constructor类的getDeclaredConstructors来获取所有构造函数,然后再用newInstance来创建该对象,在创建过程中只有其中一个构造函数可以成功创建对象,另外两个均失败,请教这个是啥情况?
对象:

package ClassTest;

public class MoreConstructor {
public String str;
public int i1;
public int i2;
public int i3;
public MoreConstructor() {
str="默认";
i1=0;
i2=0;
i3=0;
}
public MoreConstructor(String str,int i1) {
this.str=str;
this.i1=i1;
i2=0;
i3=0;
}
public MoreConstructor(String str,int i1,int i2,int i3) {
this.str=str;
this.i1=i1;
this.i2=i2;
this.i3=i3;
}
public void ShowInfor() {
System.out.println(this.str);
System.out.println(this.i1);
System.out.println(this.i2);
System.out.println(this.i3);
}
}


调用程序:

package ClassTest;

import java.lang.reflect.Constructor;

public class MoreConstructorRun {
public static void main(String[] args) {
MoreConstructor MC=new MoreConstructor();
Class cl;
cl=MC.getClass();
Constructor[] csArray;
csArray=cl.getDeclaredConstructors();
// MC.ShowInfor();
MoreConstructor MC1=new MoreConstructor("一个",10);
// MC1.ShowInfor();
MoreConstructor MC2=new MoreConstructor("两个",10,20,30);
// MC2.ShowInfor();
for(int i=0;i<csArray.length;i++) {
Constructor constructor=csArray[i];
MoreConstructor MC0=null;
// csArray[i].setAccessible(true);
Class[] clTmp=constructor.getParameterTypes();
System.out.println("构造函数中的参数为;");
for(int j=0;j<clTmp.length;j++) {
System.out.println(clTmp[j].toString());
}
try {
if(i==0) {
MC0=(MoreConstructor) constructor.newInstance();
MC0.ShowInfor();
}
else if(i==1) {
MC0=(MoreConstructor) constructor.newInstance("一个",10);
MC0.ShowInfor();
}
else if(i==2) {
MC0=(MoreConstructor) constructor.newInstance("两个",10,20,30);
MC0.ShowInfor();
}
}catch(Exception e) {
System.out.println("创建对象异常");
constructor.setAccessible(true);
}
}
}
}

...全文
360 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jack54877012 2017-11-20
  • 打赏
  • 举报
回复
引用 9 楼 qq_19314763 的回复:
对了 忘了提醒lz一个小问题,你的题目写的不太对,getDeclaredConstructors是Class类的方法,而不是constructor的方法,通过该方法获取的构造器属于constructor类(也就是该方法返回类型是构造器类,但方法本身不是)
是的,感谢!
zycxnanwang 2017-11-20
  • 打赏
  • 举报
回复
看完帖子学到了类获得的构造器数组没有特定顺序, 6666
迟到_啦 2017-11-20
  • 打赏
  • 举报
回复
对了 忘了提醒lz一个小问题,你的题目写的不太对,getDeclaredConstructors是Class类的方法,而不是constructor的方法,通过该方法获取的构造器属于constructor类(也就是该方法返回类型是构造器类,但方法本身不是)
迟到_啦 2017-11-20
  • 打赏
  • 举报
回复
哈哈 我们有中文版 API


确实明确指出没有顺序 ,这样的话我修改了一下if else语句,这样就不怕执行顺序随机了
jack54877012 2017-11-20
  • 打赏
  • 举报
回复
引用 5 楼 qq_19314763 的回复:
[quote=引用 1 楼 jack54877012 的回复:] 运行结果: 构造函数中的参数为; class java.lang.String int int int 创建对象异常 构造函数中的参数为; class java.lang.String int 一个 10 0 0 构造函数中的参数为; 创建对象异常
2楼的解决方法是对的,我测试了一下 不过 我也不太明白为什么先取的是4个参数的构造器,我再查阅一下资料去(测试结果如下:) [/quote] 看了一下网上的资料,API文档里好像确实没有明确返回顺序: public Constructor<?>[] getDeclaredConstructors() throws SecurityException Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors. The elements in the array returned are not sorted and are not in any particular order. If the class has a default constructor, it is included in the returned array. This method returns an array of length 0 if this Class object represents an interface, a primitive type, an array class, or void. See The Java Language Specification, section 8.2. 也就是说,不能直接按顺序去判断,得自行添加判断条件
jack54877012 2017-11-20
  • 打赏
  • 举报
回复
引用 5 楼 qq_19314763 的回复:
[quote=引用 1 楼 jack54877012 的回复:] 运行结果: 构造函数中的参数为; class java.lang.String int int int 创建对象异常 构造函数中的参数为; class java.lang.String int 一个 10 0 0 构造函数中的参数为; 创建对象异常
2楼的解决方法是对的,我测试了一下 不过 我也不太明白为什么先取的是4个参数的构造器,我再查阅一下资料去(测试结果如下:) [/quote] 是的,试了一下确实是顺序问题,而且按照原来的代码,会时有发生无参构造函数可以创建成功,另外两个创建不成功的情况:

构造函数中的参数为;
默认
0
0
0
构造函数中的参数为;
class java.lang.String
int
int
int
创建对象异常
构造函数中的参数为;
class java.lang.String
int
创建对象异常
也就是说这个感觉是有点随机的情况 而修改过后多次运行也会有创建失败的情况偶发出现:

构造函数中的参数为;
创建对象异常
构造函数中的参数为;
class java.lang.String
int
int
int
创建对象异常
构造函数中的参数为;
class java.lang.String
int
创建对象异常
是不是有点随机的情况?
迟到_啦 2017-11-20
  • 打赏
  • 举报
回复
引用 1 楼 jack54877012 的回复:
运行结果:
构造函数中的参数为;
class java.lang.String
int
int
int
创建对象异常
构造函数中的参数为;
class java.lang.String
int
一个
10
0
0
构造函数中的参数为;
创建对象异常


2楼的解决方法是对的,我测试了一下 不过 我也不太明白为什么先取的是4个参数的构造器,我再查阅一下资料去(测试结果如下:)

迟到_啦 2017-11-20
  • 打赏
  • 举报
回复
引用 2 楼 pany1209 的回复:
参数4个的构造器再 Constructor[] csArray里面下标0,if else判断改为2 1 0不是0 1 2
确实是这样额,,为什么不是按顺序取得构造器呢
jack54877012 2017-11-20
  • 打赏
  • 举报
回复
引用 2 楼 pany1209 的回复:
参数4个的构造器再 Constructor[] csArray里面下标0,if else判断改为2 1 0不是0 1 2
.....晕!不是按照声明顺序去返回构造函数的么
李德胜1995 2017-11-20
  • 打赏
  • 举报
回复
参数4个的构造器再 Constructor[] csArray里面下标0,if else判断改为2 1 0不是0 1 2
jack54877012 2017-11-20
  • 打赏
  • 举报
回复
运行结果: 构造函数中的参数为; class java.lang.String int int int 创建对象异常 构造函数中的参数为; class java.lang.String int 一个 10 0 0 构造函数中的参数为; 创建对象异常
该课程由付强老师主讲,系统的、全面的、具体的讲解了java入门的知识。可以使初级的学员入门。Java入门Java的历史、Java的版本、Java的优势、软件行业前景Java开发环境搭建、编写Java入门练习虚拟机的运行机制、Java的平台无关性、虚拟机垃圾回收机制基础语法关键字、标识符、Java数据类型分类、基础数据类型、取值范围变量、常量、三种注释、生成doc文档、运算符、表达式if语句、switch语句、嵌套判断for语句、while语句、do-while语句、嵌套循环类和对象面向过程和面向对象的区别类的构成、访问修饰符、对象的内存分配this关键字、按值传递与按引用传递、对象的初始化顺序高级类特性类的继承、父子类的初始化顺序、单继承性方法的覆盖、重载、super关键字、多态、instanceof关键字、强制类型转换、static关键字、final关键字数组和枚举一维数组的应用及内存分配多维数组的应用及内存分配数组的复制、数组的按引用传递排序算法:冒泡、直接选择、插入选择、希尔、快速、归并、堆排序Arrays工具类的应用枚举类型的应用常见类的使用Object类的底层及应用、Objects类String类的底层及应用、正则表达式StringBuffer和StringBuilder的底层及应用Math类的应用、包装类的应用日期类的应用:Date、DateFormat、Calendar、LocalDateTime、Instant、LocalDate、MonthDay、ZonedDateTime、YearMonth、新旧日期转换BigInteger和BingDecimal、DecimalFormatSystem类、Scanner类抽象类和接口抽象类的规则及应用接口的规则及应用默认方法、静态方法、函数式接口、Lambda表达式异常异常的定义异常的处理:抓(try-catch-finally)、抛(throws)异常的分类、自定义异常的应用、throw关键字集合框架集合框架结构:接口、实现类Collection接口的方法、Set接口的方法、List接口的方法、Map接口的方法Array、Linked、Hash、Tree底层实现原理泛型的作用、Collections工具类、历史集合类I/O流Path类的原理及应用、Files类的原理及应用文件字节流FileInputStream的原理及应用对象类、缓冲流、数据流的原理及应用字符流的原理及应用多线程进程与线程的概念、查看线程对象Java内存模型线程的创建与启动:扩展Thread类、实现Runnable接口、实现Callable接口、线程池线程状态的转换:新建、就绪、运行、阻塞、死亡线程的调度:sleep、yield、join、interrupt、wait后台线程、定时任务线程的并发与同步、同步锁、同步块、线程安全的类Lock接口、CAS、volatile修饰符内部类成员内部类、本地内部类的应用匿名内部类的原理及引用、Lambda表达式设计模式基础设计模式概念、框架概念7大设计原则:开闭原则、依赖倒置原则、单一职责原则、接口隔离原则、迪米特原则、里氏替换原则、合成复用原则单例模式、工厂模式、模板模式、代理模式、装饰模式、适配器模式、外观模式、策略模式、观察者模式、命令模式、备忘录模式、观察者模式反射反射包Class类的使用反射获取类属性、方法、构造器通过反射创建类对象/通过反射调用方法反射的应用

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧