首页 > 代码库 > java反射机制(一)—— 利用反射机制实例化对象

java反射机制(一)—— 利用反射机制实例化对象

一、Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(度娘文库是这么说的)


二、这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class<T>类的newnstance()方法进行实例化,下面我就通过代码来展示:

1、首先我建了一个Person类作为测试用的:

package com.reflect.test;

/**
 * @author 林楷鹏
 * @description 测试用的
 * @create 2014-11-27下午9:34:00
 * 
 */
public class Person {

	private int age;
	private String name;
	
	public Person() {
		
	}
	public Person(String name) {
		this.name = name;
	}
	public Person(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public String getName() {
		return name;
	}
}


2、通过构造函数:

package com.reflect.test;

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

/**
 * @author 林楷鹏
 * @description 反射机制,通过构造函数实例化对象
 * @create 2014-11-27下午9:32:05
 * 
 */
public class ReflectConstructor {

	
	public static void main(String[] args) {
		Person person = new Person();
		try {
			Class<?> cls = Class.forName(person.getClass().getName());
			//参数类型
			Class<?>[] params = {Integer.TYPE, String.class};
			//参数值
			Object[] values = {15, "kroc"};
			//构造有两个参数的构造函数
			Constructor<?> constructor = cls.getDeclaredConstructor(params);
			//根据构造函数,传入值生成实例
			Object object = constructor.newInstance(values);
			Method getAge = cls.getDeclaredMethod("getAge");
			Method getName = cls.getDeclaredMethod("getName");
			System.out.println("getAge = " + (Integer)getAge.invoke(object));
			System.out.println("getName = " + (String)getName.invoke(object));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			System.out.println("ClassNotFoundException");
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}

}
可以看到代码中,以下两行是比较重要的,第一行是通过参数个数去获取一个构造函数,记得这里传的参数的个数和类型要跟Person里面构造函数里面的相符,而参数类型也要和参数值values的类型一样,我这里就封装成params和values一起传进去

//构造有两个参数的构造函数
			Constructor<?> constructor = cls.getDeclaredConstructor(params);
			//根据构造函数,传入值生成实例
			Object object = constructor.newInstance(values);

运行结果如下:




3、第二种方式是通过Class<T>类的newnstance()方法进行初始化:

package com.reflect.test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * @author 林楷鹏
 * @description 反射机制,通过newInstance()实例化对象
 * @create 2014-11-27下午9:41:01
 * 
 */
public class ReflectMethod {

	
	public static void main(String[] args) {
		Person person = new Person();
		try {
			Class<?> cls = Class.forName(person.getClass().getName());
			//生成实例,调用默认无参构造函数
			Object object = cls.newInstance();
			Method setName = cls.getDeclaredMethod("setName", String.class);
			Method setAge = cls.getDeclaredMethod("setAge", Integer.TYPE);
			setName.invoke(object, "KrocLin");
			setAge.invoke(object, 20);
			Method getAge = cls.getDeclaredMethod("getAge");
			Method getName = cls.getDeclaredMethod("getName");
			System.out.println("getAge = " + (Integer)getAge.invoke(object));
			System.out.println("getName = " + (String)getName.invoke(object));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			System.out.println("ClassNotFoundException");
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}

}
代码可以知道,其实用newInstance()是调用Person的默认无参构造函数的,所以本质上还是跟上一种方式一样。

运行结果:


三、关于反射机制,可以做的事情还有很多,上面我为了简单展示就类似于getName这些方法名什么的都写死了,其实还可以通过反射去获取方法名,包括方法的返回类型啊、抛出异常等等都可以通过反射机制去得到。以后有时间就再写一些关于java反射机制的文章分享下,对于这个如果哪里写错了或者有什么更好的建议麻烦评论交流。

java反射机制(一)—— 利用反射机制实例化对象