Java 反射 使用总结
本文内容纲要:
-反射机制是什么
-反射机制能做什么
-反射机制的相关API
-getDeclaredFields和getFields的区别
-实战1:通过反射,获取对象实例,并且操作对象的方法
-实战2:通过反射获取对象字段属性,并且赋值
-实战3:综合训练,反射操作属性和方法
-实战4:静态属性、静态方法调用
-当参数是int类型和Integer类型,反射获取方法不一样
-创建对象实例
-总结
转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/6074887.html1
本文出自【赵彦军的博客】
反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么
反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理。
反射机制的相关API
**InterFace**接口
packagecom.app;
publicinterfaceInterFace{
voidread();
}
Person类
packagecom.app;
publicclassPersonimplementsInterFace{
privateStringid;
privateStringname;
publicStringage;
//构造函数1
publicPerson(){
}
//构造函数2
publicPerson(Stringid){
this.id=id;
}
//构造函数3
publicPerson(Stringid,Stringname){
this.id=id;
this.name=name;
}
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetAge(){
returnage;
}
publicvoidsetAge(Stringage){
this.age=age;
}
/**
*静态方法
*/
publicstaticvoidupdate(){
}
@Override
publicvoidread(){
}
}
-
获取类:3种方法
packagecom.app;
publicclassT1{
publicstaticvoidmain(String[]args){ //第一种方法:forName try{ Class<?>class1=Class.forName("com.app.Person"); System.out.println(class1); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } //第二张方法:class Class<?>class2=Person.class; //第三种方法:getClass Personperson=newPerson(); Class<?>class3=person.getClass(); System.out.println(class2); System.out.println(class3); }
}
运行结果:
classcom.app.Person
classcom.app.Person
classcom.app.Person
-
获取所有的方法:getMethods()
packagecom.app;
importjava.lang.reflect.Method;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person"); //获取所有的公共的方法 Method[]methods= class1.getMethods(); for(Methodmethod:methods){ System.out.println(method); } }catch(ClassNotFoundExceptione){ e.printStackTrace(); } }
}
运行结果:
//自定义方法
publicstaticvoidcom.app.Person.update()
publicjava.lang.Stringcom.app.Person.getName()
publicvoidcom.app.Person.read()
publicjava.lang.Stringcom.app.Person.getId()
publicvoidcom.app.Person.setName(java.lang.String)
publicvoidcom.app.Person.setId(java.lang.String)
//父类Object类方法
publicfinalvoidjava.lang.Object.wait()throwsjava.lang.InterruptedException
publicfinalvoidjava.lang.Object.wait(long,int)throwsjava.lang.InterruptedException
publicfinalnativevoidjava.lang.Object.wait(long)throwsjava.lang.InterruptedException
publicbooleanjava.lang.Object.equals(java.lang.Object)
publicjava.lang.Stringjava.lang.Object.toString()
publicnativeintjava.lang.Object.hashCode()
publicfinalnativejava.lang.Classjava.lang.Object.getClass()
publicfinalnativevoidjava.lang.Object.notify()
publicfinalnativevoidjava.lang.Object.notifyAll()
-
获取所有实现的接口:getInterfaces()
packagecom.app;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person"); //获取所有的接口 Class<?>[]interS=class1.getInterfaces(); for(Class<?>class2:interS){ System.out.println(class2); } }catch(ClassNotFoundExceptione){ e.printStackTrace(); } }
}
运行结果:
interfacecom.app.InterFace
-
获取父类:getSuperclass()
packagecom.app;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person"); //获取父类 Class<?>superclass=class1.getSuperclass(); System.out.println(superclass); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } }
}
运行结果:
//父类是Object类
classjava.lang.Object
-
获取所有的构造函数:getConstructors()
packagecom.app;
importjava.lang.reflect.Constructor;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person"); //获取所有的构造函数 Constructor<?>[]constructors=class1.getConstructors(); for(Constructor<?>constructor:constructors){ System.out.println(constructor); } }catch(ClassNotFoundExceptione){ e.printStackTrace(); } }
}
运行结果:
publiccom.app.Person(java.lang.String,java.lang.String)
publiccom.app.Person(java.lang.String)
publiccom.app.Person()
-
获取所有的属性:getDeclaredFields();
packagecom.app;
importjava.lang.reflect.Constructor; importjava.lang.reflect.Field;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person"); //取得本类的全部属性 Field[]field=class1.getDeclaredFields(); for(Fieldfield2:field){ System.out.println(field2); } }catch(ClassNotFoundExceptione){ e.printStackTrace(); } }
}
运行结果:
privatejava.lang.Stringcom.app.Person.id
privatejava.lang.Stringcom.app.Person.name
可以看出属性的修饰符是:private,数据类型:String,名字:id/name
-
创建实例:newInstance()
packagecom.app;
publicclassT1{
publicstaticvoidmain(String[]args){ try{ //创建类 Class<?>class1=Class.forName("com.app.Person");; //创建实例化:相当于new了一个对象 Objectobject=class1.newInstance(); //向下转型 Personperson=(Person)object; }catch(ClassNotFoundExceptione){ e.printStackTrace(); }catch(InstantiationExceptione){ e.printStackTrace(); }catch(IllegalAccessExceptione){ e.printStackTrace(); } }
}
getDeclaredFields和getFields的区别
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。
小例子
packagecom.app;
importjava.lang.reflect.Field;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");;
//获得所有的字段属性:包括
Field[]declaredFields=class1.getDeclaredFields();
Field[]fields=class1.getFields();
for(Fieldfield:declaredFields){
System.out.println("de--"+field);
}
for(Fieldfield:fields){
System.out.println("fields--"+field);
}
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果:
de--privatejava.lang.Stringcom.app.Person.id
de--privatejava.lang.Stringcom.app.Person.name
de--publicjava.lang.Stringcom.app.Person.age
fields--publicjava.lang.Stringcom.app.Person.age
实战1:通过反射,获取对象实例,并且操作对象的方法
packagecom.app;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");;
//创建实例化:相当于new了一个对象
Objectobject=class1.newInstance();
//向下转型
Personperson=(Person)object;
person.setId("100");
person.setName("jack");
System.out.println("id:"+person.getId()+"name:"+person.getName());
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}
}
}
运行结果:
id:100name:jack
实战2:通过反射获取对象字段属性,并且赋值
packagecom.app;
importjava.lang.reflect.Field;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");
//创建实例
Objectperson=class1.newInstance();
//获得id属性
FieldidField=class1.getDeclaredField("id");
//给id属性赋值
idField.set(person,"100");
//打印person的属性值
System.out.println(idField.get(person));
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(NoSuchFieldExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果:
java.lang.IllegalAccessException:Classcom.app.T1cannotaccessamemberofclasscom.app.Personwithmodifiers"private"
atsun.reflect.Reflection.ensureMemberAccess(UnknownSource)
atjava.lang.reflect.AccessibleObject.slowCheckMemberAccess(UnknownSource)
atjava.lang.reflect.AccessibleObject.checkAccess(UnknownSource)
atjava.lang.reflect.Field.set(UnknownSource)
atcom.app.T1.main(T1.java:20)
程序崩溃,原因是:id这个属性的是private私有的,不能修改它的值。
改进:
添加idField.setAccessible(true);
完整的代码为:
packagecom.app;
importjava.lang.reflect.Field;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");
//创建实例
Objectperson=class1.newInstance();
//获得id属性
FieldidField=class1.getDeclaredField("id");
//打破封装实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
//由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
idField.setAccessible(true);
//给id属性赋值
idField.set(person,"100");
//打印person的属性值
System.out.println(idField.get(person));
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(NoSuchFieldExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果:
100
实战3:综合训练,反射操作属性和方法
packagecom.app;
importjava.lang.reflect.Field;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");
//创建实例
Objectperson=class1.newInstance();
//获得id属性
FieldidField=class1.getDeclaredField("id");
//打破封装实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
//由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
idField.setAccessible(true);
//给id属性赋值
idField.set(person,"100");
//获取setName()方法
MethodsetName=class1.getDeclaredMethod("setName",String.class);
//打破封装
setName.setAccessible(true);
//调用setName方法。
setName.invoke(person,"jack");
//获取name字段
FieldnameField=class1.getDeclaredField("name");
//打破封装
nameField.setAccessible(true);
//打印person的id属性值
Stringid_=(String)idField.get(person);
System.out.println("id:"+id_);
//打印person的name属性值
Stringname_=(String)nameField.get(person);
System.out.println("name:"+name_);
//获取getName方法
MethodgetName=class1.getDeclaredMethod("getName");
//打破封装
getName.setAccessible(true);
//执行getName方法,并且接收返回值
Stringname_2=(String)getName.invoke(person);
System.out.println("name2:"+name_2);
}catch(IllegalArgumentExceptione){
e.printStackTrace();
}catch(InvocationTargetExceptione){
e.printStackTrace();
}catch(NoSuchMethodExceptione){
e.printStackTrace();
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(NoSuchFieldExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果:
id:100
name:jack
name2:jack
实战4:静态属性、静态方法调用
定义Util类
packagecom.app;
publicclassUtil{
publicstaticStringname="json";
/**
*没有返回值,没有参数
*/
publicstaticvoidgetTips(){
System.out.println("执行了---------1111");
}
/**
*有返回值,没有参数
*/
publicstaticStringgetTip(){
System.out.println("执行了---------2222");
return"tip2";
}
/**
*没有返回值,有参数
*@paramname
*/
publicstaticvoidgetTip(Stringname){
System.out.println("执行了---------3333参数:"+name);
}
/**
*有返回值,有参数
*@paramid
*@return
*/
publicstaticStringgetTip(intid){
System.out.println("执行了---------4444参数:"+id);
if(id==0){
return"tip1444--1";
}else{
return"tip1444--2";
}
}
}
完整小例子:
packagecom.app;
importjava.lang.reflect.Field;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Util");
//获取nameField属性
FieldnameField=class1.getDeclaredField("name");
//获取nameField的值
Stringname_=(String)nameField.get(nameField);
//输出值
System.out.println(name_);
//没有返回值,没有参数
MethodgetTipMethod1=class1.getDeclaredMethod("getTips");
getTipMethod1.invoke(null);
//有返回值,没有参数
MethodgetTipMethod2=class1.getDeclaredMethod("getTip");
Stringresult_2=(String)getTipMethod2.invoke(null);
System.out.println("返回值:"+result_2);
//没有返回值,有参数
MethodgetTipMethod3=class1.getDeclaredMethod("getTip",String.class);
Stringresult_3=(String)getTipMethod3.invoke(null,"第三个方法");
System.out.println("返回值:"+result_3);
//有返回值,有参数
MethodgetTipMethod4=class1.getDeclaredMethod("getTip",int.class);
Stringresult_4=(String)getTipMethod4.invoke(null,1);
System.out.println("返回值:"+result_4);
}catch(InvocationTargetExceptione){
e.printStackTrace();
}catch(IllegalArgumentExceptione){
e.printStackTrace();
}catch(NoSuchMethodExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(NoSuchFieldExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果:
json
执行了---------1111
执行了---------2222
返回值:tip2
执行了---------3333参数:第三个方法
返回值:null
执行了---------4444参数:1
返回值:tip1444--2
当参数是int类型和Integer类型,反射获取方法不一样
-
当参数是int类型时
/** *没有返回值,有参数 *@paramid */ publicstaticvoidgetTip(intid){
}
获取方法的时候需要用:int.class
。不能使用Integer.class
.会报错。
MethodgetTipMethod4=class.getDeclaredMethod("getTip",int.class);
Stringresult_4=(String)getTipMethod4.invoke(null,1);
System.out.println("返回值:"+result_4);
-
当参数是Integer类型时
/** *没有返回值,有参数 *@paramid */ publicstaticvoidgetTip(Integerid){
}
获取方法的时候需要用:Integer.class
。不能使用int.class
.会报错。
MethodgetTipMethod4=class.getDeclaredMethod("getTip",Integer.class);
Stringresult_4=(String)getTipMethod4.invoke(null,1);
System.out.println("返回值:"+result_4);
创建对象实例
Person类
packagecom.app;
publicclassPerson{
privateStringid;
privateStringname;
//构造函数1
publicPerson(){
System.out.println("构造函数无参");
}
//构造函数2
publicPerson(Stringid){
this.id=id;
System.out.println("构造函数id:"+id);
}
//构造函数3
publicPerson(Stringid,Stringname){
this.id=id;
this.name=name;
System.out.println("构造函数id:"+id+"name:"+name);
}
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
创建实例实战
packagecom.app;
importjava.lang.reflect.Constructor;
importjava.lang.reflect.InvocationTargetException;
publicclassT1{
publicstaticvoidmain(String[]args){
try{
//创建类
Class<?>class1=Class.forName("com.app.Person");
//无参构造函数
Objectobject=class1.newInstance();
//有参构造函数:一个参数
Constructor<?>constructor=class1.getDeclaredConstructor(String.class);
constructor.newInstance("1000");
//有参构造函数:二个参数
Constructor<?>constructor2=class1.getDeclaredConstructor(String.class,String.class);
constructor2.newInstance("1001","jack");
}catch(InstantiationExceptione){
e.printStackTrace();
}catch(IllegalAccessExceptione){
e.printStackTrace();
}catch(InvocationTargetExceptione){
e.printStackTrace();
}catch(IllegalArgumentExceptione){
e.printStackTrace();
}catch(NoSuchMethodExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}
}
}
运行结果
构造函数无参
构造函数id:1000
构造函数id:1001name:jack
总结
-
Class类提供了四个public方法,用于获取某个类的构造方法。
ConstructorgetConstructor(Class[]params)根据构造函数的参数,返回一个具体的具有public属性的构造函数 ConstructorgetConstructors()返回所有具有public属性的构造函数数组 ConstructorgetDeclaredConstructor(Class[]params)根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性) ConstructorgetDeclaredConstructors()返回该类中所有的构造函数数组(不分public和非public属性)
-
四种获取成员方法的方法
MethodgetMethod(Stringname,Class[]params)根据方法名和参数,返回一个具体的具有public属性的方法 Method[]getMethods()返回所有具有public属性的方法数组 MethodgetDeclaredMethod(Stringname,Class[]params)根据方法名和参数,返回一个具体的方法(不分public和非public属性) Method[]getDeclaredMethods()返回该类中的所有的方法数组(不分public和非public属性)
-
四种获取成员属性的方法
FieldgetField(Stringname)根据变量名,返回一个具体的具有public属性的成员变量 Field[]getFields()返回具有public属性的成员变量的数组 FieldgetDeclaredField(Stringname)根据变量名,返回一个成员变量(不分public和非public属性) Field[]getDelcaredField()返回所有成员变量组成的数组(不分public和非public属性)
本文内容总结:反射机制是什么,反射机制能做什么,反射机制的相关API,getDeclaredFields和getFields的区别,实战1:通过反射,获取对象实例,并且操作对象的方法,实战2:通过反射获取对象字段属性,并且赋值,实战3:综合训练,反射操作属性和方法,实战4:静态属性、静态方法调用,当参数是int类型和Integer类型,反射获取方法不一样,创建对象实例,总结,
原文链接:https://www.cnblogs.com/zhaoyanjun/p/6074887.html