使用Java中的反射调用构造函数

时间:2020-02-23 14:34:51  来源:igfitidea点击:

在本教程中,我们将看到如何使用Java中的反射来调用构造函数。

我们可以使用反射在运行时检索类和实例化对象的构造函数。

java.lang.reflect.Constructor用于实例化对象。

实例化构造函数没有参数

如果我们想要在运行时使用args构造函数创建对象,我们可以如下执行。

Class<?> cl = Class.forName("org.igi.theitroad.Color");
			
//Call no-args constructor
Object newInstance = cl.newInstance();
System.out.println(newInstance);

其中 Class.forName("org.igi.theitroad.Color")用于加载类并获取类型的对象 Class我们可以在运行时检索大量信息,如构造函数,方法和注释等 Class目的。

你需要替换 org.igi.theitroad.Color使用className,我们要在运行时实例化对象。 cl.newInstance()可用于在运行时使用No-Args构造函数创建对象。

实例化构造函数与参数

如果我们想要使用参数实例化构造函数,则需要将构造函数与参数一起检索,然后传递参数以实例化。

Class<?> cl = Class.forName("org.igi.theitroad.Color");
			
//Call parameterized constructor
Class<?>[] type = { String.class,String.class };
 
//get parameterized constructor which takes 2 Strings as parameters
Constructor<?> cons = cl.getConstructor(type);
//String arguments
Object[] obj = { "Red","#FF0000"};
Object newInstancePC = cons.newInstance(obj);
  • 你需要通过 Class[]getConstructor()方法和检索实例 java.lang.reflect.Constructorcl
  • 经过 Object[]到cons.newinstance用传递参数构造对象。

我们还可以使用参数类型 cons.getParameterTypes()

Class[] parameterTypes= cons.getParameterTypes();

让我们用一个例子来看看这个。
考虑一个名字的程序 Color有两个属性 namehtmlCode

package org.igi.theitroad;
 
public class Color {
 
	String name;
	String htmlCode;
 
	public Color(String name, String htmlCode) {
		super();
		this.name = name;
		this.htmlCode = htmlCode;
	}
 
	public Color() {
		name = "black";
		htmlCode = "#000000";
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public String getHtmlCode() {
		return htmlCode;
	}
 
	public void setHtmlCode(String htmlCode) {
		this.htmlCode = htmlCode;
	}
 
	@Override
	public String toString() {
		return "Color [name:" + name + " HtmlCode:" + htmlCode + "]";
	}
}

创建名为的主类 ConstuctorReflectionMain

package org.igi.theitroad;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
 
public class ConstuctorReflectionMain {
 
	public static void main(String[] args) {
		
		try {
			Class<?> cl = Class.forName("org.igi.theitroad.Color");
			
			System.out.println("====================");
			System.out.println("Calling default constructor");
			System.out.println("====================");
			//Call default constructor
			Object newInstance = cl.newInstance();
			System.out.println(newInstance);
			
			System.out.println("====================");
			System.out.println("Calling parameterized constructor");
			System.out.println("====================");
			Class<?>[] type = { String.class,String.class };
			
			//get parameterized constructor which takes 2 Strings as parameters
			Constructor<?> cons = cl.getConstructor(type);
			//String arguments
			Object[] obj = { "Red","#FF0000"};
			Object newInstancePCObj = cons.newInstance(obj);
			
			//cast it to required type
			Color color=(Color) newInstancePCObj;
			System.out.println(color);
			
		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException 
				     | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		} 
	}
}

运行上面的程序时,我们将得到以下输出:输出:

====================
Calling default constructor
====================
Color [name:black HtmlCode:#000000]
====================
Calling parameterized constructor
====================
Color [name:Red HtmlCode:#FF0000]

正如我们所看到的,我们能够使用对象来使用 java.lang.reflect.Constructor使用反射的运行时间。

原始类型的构造函数参数

如果,我们可以使用具有原始类型的构造函数参数 .class后缀。
例如:如果参数类型是 int,然后你可以使用 int.class同时获得该类型的构造函数。

让我们通过示例来理解:考虑一下程序 Employee具有属性: nameage

package org.igi.theitroad;
 
public class Employee {
 
	String name;
	int age;
 
	public Employee(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public int getAge() {
		return age;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
 
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + "]";
	}
}

创建名为的主类 ConstructorParameterPrimMain

package org.igi.theitroad;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
 
public class ConstructorParameterPrimMain {
 
public static void main(String[] args) {
		
		try {
			Class<?> cl = Class.forName("org.igi.theitroad.Employee");
			
			Class<?>[] type = { String.class,int.class };
			
			//get parameterized constructor which takes 2 Strings as parameters
			Constructor<?> cons = cl.getConstructor(type);
			//String arguments
			Object[] obj = { "igi",28};
			Object newInstanceObj = cons.newInstance(obj);
			
			//cast it to required type
			Employee emp=(Employee) newInstanceObj;
			System.out.println(emp);
			
		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException 
				     | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		} 
	}
 
}

运行上面的程序时,我们将得到以下输出:输出:

Employee [name=igi, age=28]

你也可以通过 Integer.Type代替 int.class

Class<?>[] type = { String.class,Integer.Type };