使用反射调用构造器

本文介绍了如何通过反射机制获取并调用Java类的构造器。首先,需要获取类的字节码对象,然后使用`getConstructor()`或`getDeclaredConstructor()`方法获取构造器。反射调用构造器的主要用途是在框架中,由于提供的参数通常是字符串,无法直接使用`new`关键字创建对象。此外,对于私有的构造器,还需调用`setAccessible(true)`进行访问。

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

通过反射来获取某一个类的构造器可以分两步:
1.获取该类的字节码对象 (可参考文章 反射机制  )
2.从该字节码对象中去找需要获取的构造器(查看API文档)

获取所有构造器有两个方法:

1.getConstructor():获取当前Class所表示类的所有public方法

2.getDeclaredConstructor():获取所有构造器

 

获取指定的一个构造器的方法:

我们知道构造方法的方法名是与类名相同的,所以不能通过方法名来区分各个方法。在调用构造方法时候是用参数类型,参数个数等区分的,那这里也同样。


import java.lang.reflect.Constructor;

class User {
	public User() {

	}

	public User(String name) {

	}

	private User(String name, int age) {

	}
}

// 获取构造器
public class GetConstructorDemo {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		// getAll();
		getOne();
	}

	// 获取指定的一个构造器
	private static void getOne() throws NoSuchMethodException, SecurityException {
		// 1.获取构造器所在类的字节码对象
		Class<User> clz = User.class;
		// 2.获取clz对象中所有的构造器
		Constructor<User> con = clz.getConstructor();
		System.out.println(con);
		con = clz.getConstructor(String.class);
		System.out.println(con);
		// 因为这个方法在User中是private,所以要用getDeclaredConstructor
		con = clz.getDeclaredConstructor(String.class, int.class);
		System.out.println(con);
	}

	// 获取所有的构造器
	private static void getAll() {
		// 1.获取构造器所在类的字节码对象
		Class<User> clz = User.class;
		// 2.获取clz对象中所有的构造器

		// getConstructor():获取当前Class所表示类的public方法
		Constructor<?>[] cs = clz.getConstructors();
		System.out.println(cs.length);
		for (Constructor<?> c : cs) {
			System.out.println(c);
		}
		// getDeclaredConstructor():获取所有构造器
		Constructor<?>[] cs1 = clz.getDeclaredConstructors();
		System.out.println(cs1.length);
		for (Constructor<?> c : cs1) {
			System.out.println(c);
		}
	}

}

 

 

获取构造器后就可以创建对象,构造器的作用就是创建对象。

那么为什么我们不直接用new 来创建对象,而还要通过反射这么麻烦呢?

因为在框架中提供给我们的都是字符串,无法new对象。

 

 


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//使用反射调用构造器-->创建对象

class Person {
	public Person() {
		System.out.println("无参构造器");
	}

	public Person(String name) {
		System.out.println("一个参数" + name);
	}

	private Person(String name, int age) {
		System.out.println("两个参数" + name + age);
	}
}

public class CreatObjectDemo {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// new 方式
		// new Person();
		// new Person("Ann");
		Class<Person> clz = Person.class;
		//外界可访问,且没有参数,可以Class类中的newInstance()方法直接创建对象。
		clz.newInstance();
		
		// 调用public Person()
		Constructor<Person> con = clz.getConstructor();
		// 调用构造器的newInstance方法来创建对象,并传入实参
		con.newInstance();
		
		//注意这里要重新拿到构造器,没有这一句会报错
		con=clz.getConstructor(String.class);
		con.newInstance("Ann");
		
		con=clz.getDeclaredConstructor(String.class,int.class);
		//这个方法是私有的,所以要先设置当前构造器可以访问的
		con.setAccessible(true);
		con.newInstance("Ann",18);

	}

}

 

//不能在CreatObjectDemo类中访问Person类中的private构造器 ,所有要setAccessible(true)。

 

通过反射获取方法也是同样的。

 

反射在Java中是一种强大的工具,它允许程序在运行时动态地获取类的信息以及实例化对象,包括创建对象的构造器。通过反射调用构造器创建对象的基本步骤如下: 1. **获取Class对象**:首先,你需要通过`Class.forName()`方法获取目标类的Class对象,这一步可以让你访问类的所有属性和方法。 2. **获取构造器**:使用`Class`对象的`getConstructors()`方法可以获取类的所有构造器列表,你可以根据需要选择合适的构造器,特别是指定参数列表的那个。 3. **准备参数**:如果有构造器需要参数,你需要根据构造器的参数类型构建一个参数数组。 4. **调用构造器**:使用`Constructor`对象的`newInstance()`方法,传入之前准备好的参数,构造一个新的对象实例。这个方法会调用对应的构造器来完成初始化过程。 ```java try { // 获取Class对象 Class<?> clazz = Class.forName("com.example.MyClass"); // 根据构造器参数获取构造器 Constructor<?> constructor = clazz.getConstructor(ParameterType... parameters); // 准备参数(这里假设params是一个包含所需参数的对象数组) Object[] params = {params[0], params[1]}; // 使用构造器创建对象 MyClass obj = (MyClass) constructor.newInstance(params); } catch (Exception e) { e.printStackTrace(); } ``` 请注意,反射通常用于在不确定对象类型的情况下创建对象,或者需要动态构造复杂对象的时候。但是,过度使用反射可能会降低代码的可读性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值