通过反射,可以得到指定类的所有信息
reflectTest1.properties配置文件的内容:
Class=com.test.T
以T类为测试目标
package com.test;
public class T{
private int id;
public String name;
static {
System.out.println("class Loaded!");
}
public T(){
System.out.println("T default constructed!");
}
public T(String name){
this.name=name;
System.out.println("have one parameter constructor! \tname="+name);
}
public T(int id,String name){
this.id=id;
this.name=name;
System.out.println("have two parameter constructor! \tid="+name+"\tname="+id);
}
public void m0(){
System.out.println("m0 invoked! none parameter" );
}
//有一个参数的方法
public void m1(int id){
System.out.println("m1 invoked! and It`s para :"+id);
}
public void m2(int id,String name){
System.out.println("m2 invoked! and It`s para :"+id+"\tand s:"+name);
}
}
/**
* @author 紫竹
* @function 测试java反射机制
*
*/
package com.test;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Reflect1 {
public static void main(String[] args) {
Properties props=new Properties();
try {
props.load(ReflectTest1.class.getClassLoader().getResourceAsStream("reflectTest1.properties"));
String className=props.getProperty("Class");
System.out.println("*********测试构造方法***********");
//测试构造方法
if(className!=null){
Class tClass=Class.forName(className);//这一步仅仅只是将class类装载到内存中,并没有创建这个类的对象
//调用默认构造器,即无参的那个
Object obj=tClass.newInstance();
//调用含有参数的构造器,只含有一个参数
Constructor constructor=tClass.getConstructor(String.class);
Object obj1=constructor.newInstance("zizhu");
//调用含有参数的构造器,只含有2个参数
Constructor constructor2=tClass.getConstructor(int.class,String.class);//此处还不能写成Integer.class
Object obj2=constructor2.newInstance(20,"zizhu");
System.out.println("\n*********测试方法***********");
//测试方法
//得到某个特定的方法
Method m0=tClass.getMethod("m0");
System.out.println("得到特定的方法:"+m0.getName());
//调用特定的方法
m0.invoke(obj1);//第一个参数必须传进一个实例才能调用
Method methods[]=tClass.getMethods();
for(Method m:methods){
if(m.getName().equals("m1")){
m.invoke(obj2, 21);
}else if(m.getName().equals("m2")){
m.invoke(obj, 21,"zizhu");
}else{
System.out.println("剩余的方法名字:"+m.getName());
}
}
System.out.println("\n*********测试变量***********");
//测试变量
//得到指定的变量
Field name=tClass.getField("name");//此方法不能得到private变量
System.out.println("name变量的值:"+name.get(obj1));//obj1的name值为zizhu,所以返回zizhu
//得到私有变量的方法,必须使用getDeclaredField方法,而且还需要设置setAccessible
Field id=tClass.getDeclaredField("id");
id.setAccessible(true);
System.out.println("id变量的值:"+id.getInt(obj2));//obj2实例的id值为20,所以返回20
//得到所有变量
Field fields[]=tClass.getDeclaredFields();
for(Field f:fields){
// f.setAccessible(true);
System.out.println("列出所有变量的名字(包括私有变量)"+f.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
输出结果:
*********测试构造方法***********
class Loaded!
T default constructed!
have one parameter constructor! name=zizhu
have two parameter constructor! id=zizhuname=20
*********测试方法***********
得到特定的方法:m0
m0 invoked! none parameter
剩余的方法名字:m0
m1 invoked! and It`s para :21
m2 invoked! and It`s para :21 and s:zizhu
剩余的方法名字:wait
剩余的方法名字:wait
剩余的方法名字:wait
剩余的方法名字:equals
剩余的方法名字:toString
剩余的方法名字:hashCode
剩余的方法名字:getClass
剩余的方法名字:notify
剩余的方法名字:notifyAll
*********测试变量***********
name变量的值:zizhu
id变量的值:20
列出所有变量的名字(包括私有变量)id
列出所有变量的名字(包括私有变量)name