关于Java反射机制中通过getConstructors()方法获取类中全部构造方法顺序的问题

本文详细探讨了Java反射机制中getConstructors方法获取构造方法的顺序问题,揭示了返回数组中元素位置并非按定义顺序排列的原因,建议使用更安全的方法初始化对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于Java反射机制中通过getConstructors方法获取类中全部构造方法顺序的问题


近日学习java反射机制的过程中了解到的getConstructors()方法,此方法用于取得全部构造方法,在测试过程发现了一些问题,希望与大家分享。

问题引入

以下代码用于取得Person类中的全部构造方法:

package reflectDemo01;
import java.lang.reflect.Constructor;		//导入反射包
class Person{
	private String name;
	private int age;
	public Person(String name) {			//第一个构造方法
		this.setName(name);
	}
	public Person(String name,int age) {	//第二个构造方法
		this.setName(name);
		this.setAge(age);
	}
	public void setName(String name) {
		this.name=name;
	}
	public void setAge(int age) {
		this.age=age;
	}
	public String toString() {				//覆写toString()方法
		return "姓名:"+this.name+"  年龄:"+this.age;
	}
}
public class ReflectDemo01 {
	public static void main(String args[]) {
		Class<?>c=null;									//声明Class对象
		try {
			c=Class.forName("reflectDemo01.Person");	//实例化Class对象
		} catch (ClassNotFoundException e) {
			e.printStackTrace();						//处理异常
		}			
		Constructor<?> cons[]=c.getConstructors();		//取得全部公共构造方法
		for(int i=0;i<cons.length;i++) {
			System.out.println(cons[i]);				//循环输出
		}
	}
}

运行结果如下:
两个构造方法的运行结果
通过运行结果可以看到返回的对象数组中构造方法的顺序是定义的顺序
这时将定义的两个构造方法位置交换:

public Person(String name,int age) {	//原第二个构造方法
		this.setName(name);
		this.setAge(age);
	}
	public Person(String name) {		//原第一个构造方法
		this.setName(name);
	}

得到如下结果:
两个构造方法交换后的结果
输出结果也交换了顺序,与定义的顺序一致。那我们是否能得出通过getConstructors()方法获取的构造方法顺序与定义顺序一致的结论呢?

此时将一个无参构造方法加入代码,:

	public Person(){}						//新加入的无参构造
	public Person(String name,int age) {	//原第二个构造方法
		this.setName(name);
		this.setAge(age);
	}
	public Person(String name) {			//原第一个构造方法
		this.setName(name);
	}

运行结果如下:
加入无参构造后的运行结果
运行结果可见输出顺序是逆序,并不是定义的顺序,再调换一下顺序:

	public Person(String name) {			//第一个构造方法
		this.setName(name);
	}
	public Person(String name,int age) {	//第二个构造方法
		this.setName(name);
		this.setAge(age);
	}
	public Person(){}						//新加入的无参构造

再次调换顺序后的运行结果:
三个构造方法交换顺序的运行结果
输出的结果仍是逆序,那到底getConstructors()方法返回结果的顺序如何?

问题分析

public Constructor<?>[] getConstructors() throws SecurityException

查看API文档后发现getConstructors()方法返回的是此类公共构造方法的 Constructor 对象数组 ,并没有对数组存储顺序的描述,于是我猜测此方法用了栈(Stack)的存储方式,最后用先进后出(FILO)的方式输出。

为了验证猜测,我向Person类中添加了一个浮点型(Float)的属性score,并增加了一个构造方法。

	private String name;
	private int age;	
	private float score;
	public Person(){}							//第一个无参构造
	public Person(String name) {				//第二个构造方法
		this.setName(name);
	}
	public Person(String name,int age) {		//第三个构造方法
		this.setName(name);
		this.setAge(age);
	}	
	public Person(float score) {}				//新增的第四个构造方法

运行结果:
增加之后
此时无论怎么调换方法顺序,仍是逆序输出,但再次加入2个构造方法之后,顺序发生了变化

public Person(){}										//	第一个无参构造
	public Person(String name) {						//第二个构造方法
		this.setName(name);
	}
	public Person(String name,int age) {				//第三个构造方法
		this.setName(name);
		this.setAge(age);
	}	
	public Person(float score) {}						//第四个构造方法		
	public Person(String name,float score) {}			//新增的第五个构造方法
	public Person(String name,int age,float score) {}	//新增的第六个构造方法

运行结果:
在这里插入图片描述
从运行结果可以看见输出顺序发生了变化,虽然有一定规律但并不是有序的,由此便可以得出结论。

问题结论

进一步查看API文档发现在getDeclaredConstructors()方法的描述中有这样一句话:

The elements in the array returned are not sorted and are not in any particular order.

也就是说返回数组中的元素没有排序,也没有任何特定的顺序,这样的描述同时存在于getDeclaredFields()方法和getDeclaredMethods()中。我又向Person类中加入了若干构造方法,发现分别在第3,6,13,15,27次时,输出顺序全部发生改变。由此可以得出结论:

① 在取得全部构造方法,普通方法和属性的时候,返回数组里元素的位置是完全随机的。

② 这种随机指的不是每次执行返回的结果不同,而是随着方法和属性的增加而改变返回顺序。

所以不要采用getConstructors()方法,用数组下标获取构造方法的方式初始化对象,以免以后在类中新增构造方法时出现异常
可以采用较为安全的getConstrutor()方法指定参数类型,再通过newInstance()方法为对象初始化:

Constructor<?> con1=c.getConstructor(String.class,int.class);		//指定参数类型
		Person per=(Person)con1.newInstance("MaYuKang",20);			//传入参数
		System.out.println(per);

运行结果:
在这里插入图片描述
以上所有代码及运行结果均使用Eclipse编译器,JDK10.0.1版本。如有描述不当,望大家多多纠正与补充,觉得有用就点个赞呗。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值