如何使用Java中的反射调用方法

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

在本教程中,我们将看到如何在Java中使用反射调用该方法。

创建一个名为的类 Employee.java
我们将使用反思调用此类方法。

package org.igi.theitroad.methodinvocation;
 
public class Employee {
	String name;
	int age;
	String address; 
	
	public Employee(String name, int age, String address) {
		super();
		this.name = name;
		this.age = age;
		this.address = address;
	}
 
	public void printName(String name)
	{
		System.out.println("Name:"+ name);
	}
	
	protected void printAge(int age)
	{
		System.out.println("Age : "+age);
	}
	
	private void printAddress(String address)
	{
		System.out.println("Address : "+address);
	}
	
	public String toString()
	{
		return name+"_"+age+"_"+address;
	}
	
	public static void printNationality()
	{
		System.out.println("Nationality: Netherlandsn");
	}
}

创建一个名为的主要方法 EmployeeReflectionMain.java

package org.igi.theitroad.methodinvocation;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
public class EmployeeReflectionMain {
 
	public static void main(String[] args) {
			Class<Employee> cls;
			
			//For constructor invocation
			Class[] constructorEmp = new Class[] { String.class, int.class ,String.class};
			String name="John";
			int age=20;
			String address="HighStreet";
			
			Constructor empConst;
			
		    Object[] constArgs = new Object[] { name,age,address};
			try {
				cls = (Class<Employee>) Class.forName("org.igi.theitroad.methodinvocation.Employee");
				empConst = cls.getConstructor(constructorEmp);
				Employee e = (Employee) empConst.newInstance(constArgs);
 
 
				System.out.println("================================");
				System.out.println("Calling printName method using reflection");
				System.out.println("================================");
				//String parameter
				Class[] paramString = new Class[1];
				paramString[0] = String.class;
 
				//call the printName method and need to pass string parameter
				Method method = cls.getMethod("printName", paramString);
				method.invoke(e, e.name);
				
				System.out.println("================================");
				System.out.println("Calling protected printAge method using reflection");
				System.out.println("================================");
				
				//int parameter
				Class[] paramInt = new Class[1];
				paramInt[0] = Integer.TYPE;
 
				//call the printAge method and need to pass Integer parameter
				//As printAge is protected, need to call cls.getDeclaredMethod
				method = cls.getDeclaredMethod("printAge", paramInt);
				method.invoke(e, e.age);
				
 
				System.out.println("================================");
				System.out.println("Calling toString method using reflection and capturing return value");
				System.out.println("================================");
				//no paramater
				Class noparams[] = {};
				
				method = cls.getDeclaredMethod("toString", noparams);
				String toStringStr=(String) method.invoke(e, null);
				System.out.println(toStringStr);
				
				System.out.println("================================");
				System.out.println("Calling static method printNationality using Reflection");
				System.out.println("================================");
				
				
				method = cls.getMethod("printNationality", noparams);
				method.invoke(null,null);
				
				System.out.println("================================");
				System.out.println("Calling private method printAddress using Reflection");
				System.out.println("================================");
				
				
				method = cls.getDeclaredMethod("printAddress", paramString);
				method.setAccessible(true);
				method.invoke(e,e.address);
				
			} catch (ClassNotFoundException | InstantiationException | IllegalAccessException 
					| NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
				e.printStackTrace();
			}		
	}
}

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

================================
Calling printName method using reflection
================================
Name:John
================================
Calling protected printAge method using reflection
================================
Age : 20
================================
Calling toString method using reflection and capturing return value
================================
John_20_HighStreet
================================
Calling static method printNationality using Reflection
================================
Nationality: Netherlandsn
================================
Calling private method printAddress using Reflection
================================
Address : HighStreet

说明我们需要首先创建类的对象。
我们将使用此CLS对象获取所有信息,如构造函数,方法和字段。

Class cls = (Class) Class.forName("org.igi.theitroad.methodinvocation.Employee");

调用没有参数的方法

//no parameter
				Class noparams[] = {};
				
				method = cls.getDeclaredMethod("toString", noparams);
				String toStringStr=(String) method.invoke(e, null);
				System.out.println(toStringStr);

你需要使用 getDeclareMethod()要得到 toString()方法和方法 toString()因此,没有任何参数,我们将通过空参数。

调用参数的方法

//String parameter
				Class[] paramString = new Class[1];
				paramString[0] = String.class;
 
				//call the printName method and need to pass string parameter
				Method method = cls.getMethod("printName", paramString);
				method.invoke(e, e.name);

作为 printName()是公共方法,我们可以使用 getMethod()获取对象的方法并将字符串参数传递给 printName()方法。

使用反射调用静态方法

//no parameter
				Class noparams[] = {};
		     method = cls.getMethod("printNationality", noparams);
				method.invoke(null,null);

如我们所见,我们不需要任何对象静态方法,我们正在使用方法调用方法。

使用反射调用私有方法

//String parameter
				Class[] paramString = new Class[1];
				paramString[0] = String.class;
 
	             method = cls.getDeclaredMethod("printAddress", paramString);
				method.setAccessible(true);
				method.invoke(e,e.address);

如果要使用反射调用私有方法,则需要显式调用 method.setAccessible(true),只有我们只能访问私有方法。