反射机制
首先获得类模板的方式有三种:
其次通过反射获得类的字段,方法,构造函数,并附参数:
(1)根据类模板对象获取对象的字段信息
Class clz=Class.forName("day_29_ReflectAndJson.Person");//获取类模板对象
Field[] fields=clz.getFields(); //获得该类及其父类的所有字段
for(Field field:fields)//利用增强for循环分解字段
{
int modifier=field.getModifiers();//代表访问修饰符的数字
String strModifier=Modifier.toString(modifier);//将访问权限对应的数字还原成对应的字符串
Class type=field.getType();//获得变量类型
String str=field.getName();//获得变量名
System.out.println(strModifier+" "+type+" "+str);// 输出结果: public class java.lang.String address
}
Object obj=clz.newInstance(); //根据类模板实例化对象
field.set(obj, "北京"); //给obj对象的address字段赋值为 北京
System.out.println(field.get(obj));//获取obj对象中的address字段的值
//获取本类中所有字段并赋值
Field[] fieldsDec=clz.getDeclaredFields();
for(Field field1:fieldsDec)
{
int modifiers=field1.getModifiers();
String strModifiers=Modifier.toString(modifiers);
Class type=field1.getType();
String name=field1.getName();
System.out.println(strModifiers+" "+type+" "+name);
}
//给私有字段赋值
Field fieldDec=clz.getDeclaredField("name");//这里必须调用getDeclaredFiedl();
fieldDec.setAccessible(true);//是否取消java的语法检查,因为此变量是私有的,如果不取消则无法赋值
Object obj1=clz.newInstance();
fieldDec.set(obj1, "樊康康");
System.out.println(fieldDec.get(obj1));
(2)根据类模板对象获取类中所有的方法
Class clz =Class.forName("day_29_ReflectAndJson.Person");
//前面获取本类及其父类共有的方法就不再写了 直接获得本类中的所有方法 并传参数后调用本方法
Method[] method=clz.getDeclaredMethods();//获得本类所有的方法
for(Method meth:method)
{
int modifiers=meth.getModifiers();
String modifier=Modifier.toString(modifiers);
Class returnType=meth.getReturnType();
String name= meth.getName();
Class[] parm=meth.getParameterTypes();
System.out.println(modifier+" "+returnType+" "+name+" "+parm);
}
//调用方法
Method DecMethod=clz.getDeclaredMethod("run", String.class);//得到本类中的一个私有方法
Object obj=clz.newInstance();//生成本类对象
DecMethod.setAccessible(true);//取消语法检查
DecMethod.invoke(obj, "这是run方法");//调用此方法,第一个参数为注明此方法在哪个类中,第二个参数为方法中需要传入的形参
(3)根据类模板对象获取类中指定参数的构造函数
Class clz=Class.forName("day_29_ReflectAndJson.Person");
// 利用反射获得构造函数
Constructor[] constructor=clz.getConstructors();//获得所有构造方法
for(Constructor con:constructor)
{
int modi=con.getModifiers();
String modifier=Modifier.toString(modi);
String name=con.getName();
Class[] parm=con.getParameterTypes();
System.out.println(modifier+" "+name+" "+parm);
}
Constructor constructor1=clz.getConstructor(String.class);//获得一个构造方法,String.class 表明此构造函数带一个String类型的构造函数
Object obj= constructor1.newInstance("你好构造函数");
1. Class cls=对象名.getClass();//使用这种方式获取类模板有局限性:必须现有对象才能得到类模板对象
2.Class cls=Class.forName(包名+类名的字符串);//最常用的,只要知道完全限定名(包名+类名)字符串即可获取类模板对象
3.Class cls=类名.class;//最简单,也比较常用,但必须指定类名才能获取类模板对象
可以根据类模板实例化对象:Object obj=类模板对象.newInstance();//类模板对应的对象的字节码文件中必须有无参构造函数,否则报异常。
注意:
结论1:同一种类型的对象获取的类模板对象是同一个对象
结论2:三种获取类模板的方式不同,但同于同一类型的对象获取的类模板是同一个对象.
简单而言:同一 .class文件的模板是同一对象, 使用以上三种获取的类模版对象也是同一对象
其次通过反射获得类的字段,方法,构造函数,并附参数:
(1)根据类模板对象获取对象的字段信息
Class clz=Class.forName("day_29_ReflectAndJson.Person");//获取类模板对象
Field[] fields=clz.getFields(); //获得该类及其父类的所有字段
for(Field field:fields)//利用增强for循环分解字段
{
int modifier=field.getModifiers();//代表访问修饰符的数字
String strModifier=Modifier.toString(modifier);//将访问权限对应的数字还原成对应的字符串
Class type=field.getType();//获得变量类型
String str=field.getName();//获得变量名
System.out.println(strModifier+" "+type+" "+str);// 输出结果: public class java.lang.String address
}
//根据字段名获取字段对象
Field field=clz.getField("address");Object obj=clz.newInstance(); //根据类模板实例化对象
field.set(obj, "北京"); //给obj对象的address字段赋值为 北京
System.out.println(field.get(obj));//获取obj对象中的address字段的值
//获取本类中所有字段并赋值
Field[] fieldsDec=clz.getDeclaredFields();
for(Field field1:fieldsDec)
{
int modifiers=field1.getModifiers();
String strModifiers=Modifier.toString(modifiers);
Class type=field1.getType();
String name=field1.getName();
System.out.println(strModifiers+" "+type+" "+name);
}
//给私有字段赋值
Field fieldDec=clz.getDeclaredField("name");//这里必须调用getDeclaredFiedl();
fieldDec.setAccessible(true);//是否取消java的语法检查,因为此变量是私有的,如果不取消则无法赋值
Object obj1=clz.newInstance();
fieldDec.set(obj1, "樊康康");
System.out.println(fieldDec.get(obj1));
(2)根据类模板对象获取类中所有的方法
Class clz =Class.forName("day_29_ReflectAndJson.Person");
//前面获取本类及其父类共有的方法就不再写了 直接获得本类中的所有方法 并传参数后调用本方法
Method[] method=clz.getDeclaredMethods();//获得本类所有的方法
for(Method meth:method)
{
int modifiers=meth.getModifiers();
String modifier=Modifier.toString(modifiers);
Class returnType=meth.getReturnType();
String name= meth.getName();
Class[] parm=meth.getParameterTypes();
System.out.println(modifier+" "+returnType+" "+name+" "+parm);
}
//调用方法
Method DecMethod=clz.getDeclaredMethod("run", String.class);//得到本类中的一个私有方法
Object obj=clz.newInstance();//生成本类对象
DecMethod.setAccessible(true);//取消语法检查
DecMethod.invoke(obj, "这是run方法");//调用此方法,第一个参数为注明此方法在哪个类中,第二个参数为方法中需要传入的形参
(3)根据类模板对象获取类中指定参数的构造函数
Class clz=Class.forName("day_29_ReflectAndJson.Person");
// 利用反射获得构造函数
Constructor[] constructor=clz.getConstructors();//获得所有构造方法
for(Constructor con:constructor)
{
int modi=con.getModifiers();
String modifier=Modifier.toString(modi);
String name=con.getName();
Class[] parm=con.getParameterTypes();
System.out.println(modifier+" "+name+" "+parm);
}
Constructor constructor1=clz.getConstructor(String.class);//获得一个构造方法,String.class 表明此构造函数带一个String类型的构造函数
Object obj= constructor1.newInstance("你好构造函数");
System.out.println(obj);
出处:http://blog.csdn.net/AlwaysDebug/article/details/48297091?locationNum=13&fps=1