转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/53199391
本文出自【赵彦军的博客】

反射机制是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制能做什么

反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

反射机制的相关API

InterFace 接口

package com.app;public interface InterFace {void read() ;}

Person 类

package com.app;public class Person  implements InterFace {private String id ;private String name ;public String age ;//构造函数1public Person( ){}//构造函数2public Person( String id ){this.id = id ;}//构造函数3public Person( String id  , String name ){this.id = id ;this.name = name ;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}/*** 静态方法*/public static void update(){}@Overridepublic void read() {}}
  • 获取类:3种方法
package com.app;public class T1 {public static void main(String[] args) {//第一种方法:forNametry {Class<?> class1 = Class.forName("com.app.Person");System.out.println( class1 );} catch (ClassNotFoundException e) {e.printStackTrace();}//第二张方法:classClass<?> class2 = Person.class;  //第三种方法:getClassPerson person = new Person();  Class<?> class3 = person.getClass();System.out.println( class2 );System.out.println( class3 );}}

运行结果:

class com.app.Person
class com.app.Person
class com.app.Person
  • 获取所有的方法:getMethods( )
package com.app;import java.lang.reflect.Method;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//获取所有的方法Method[] methods =  class1.getMethods() ;for (Method method : methods) {System.out.println( method );}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

//自定义方法
public static void com.app.Person.update()
public java.lang.String com.app.Person.getName()
public void com.app.Person.read()
public java.lang.String com.app.Person.getId()
public void com.app.Person.setName(java.lang.String)
public void com.app.Person.setId(java.lang.String)//父类Object类方法
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
  • 获取所有实现的接口:getInterfaces()
package com.app;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//获取所有的接口Class<?>[] interS = class1.getInterfaces() ;for (Class<?> class2 : interS ) {System.out.println( class2 );}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

interface com.app.InterFace
  • 获取父类:getSuperclass()
package com.app;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//获取父类Class<?> superclass = class1.getSuperclass() ;System.out.println( superclass );} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

//父类是Object类
class java.lang.Object
  • 获取所有的构造函数:getConstructors()
package com.app;import java.lang.reflect.Constructor;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//获取所有的构造函数Constructor<?>[] constructors = class1.getConstructors() ;for (Constructor<?> constructor : constructors) {System.out.println( constructor );}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

public com.app.Person(java.lang.String,java.lang.String)
public com.app.Person(java.lang.String)
public com.app.Person()
  • 获取所有的属性:getDeclaredFields();
package com.app;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//取得本类的全部属性Field[] field = class1.getDeclaredFields();for (Field field2 : field) {System.out.println( field2 );}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

private java.lang.String com.app.Person.id
private java.lang.String com.app.Person.name

可以看出属性的修饰符是: private , 数据类型:String ,名字:id/name

  • 创建实例:newInstance()
package com.app;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");;//创建实例化:相当于 new 了一个对象Object object = class1.newInstance() ;//向下转型Person person = (Person) object ;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
}

getDeclaredFields 和 getFields 的区别

getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

getFields()获得某个类的所有的公共(public)的字段,包括父类。

小例子

package com.app;import java.lang.reflect.Field;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");;//获得所有的字段属性:包括 Field[] declaredFields = class1.getDeclaredFields() ;Field[] fields = class1.getFields() ;for( Field field : declaredFields ){System.out.println( "de--  " +  field  );}for( Field field : fields ){System.out.println( "fields--  " +  field  );}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

de--  private java.lang.String com.app.Person.id
de--  private java.lang.String com.app.Person.name
de--  public java.lang.String com.app.Person.age
fields--  public java.lang.String com.app.Person.age

实战1:通过反射,获取对象实例,并且操作对象的方法

package com.app;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");;//创建实例化:相当于 new 了一个对象Object object = class1.newInstance() ;//向下转型              Person person = (Person) object ;person.setId( "100");person.setName( "jack") ; System.out.println( "id: " + person.getId() + " name: " + person.getName()  );} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
}

运行结果:

id: 100 name: jack

实战2:通过反射获取对象字段属性,并且赋值

package com.app;import java.lang.reflect.Field;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//创建实例Object person = class1.newInstance();//获得id 属性Field idField = class1.getDeclaredField( "id" ) ;//给id 属性赋值idField.set(  person , "100") ;//打印 person 的属性值System.out.println( idField.get( person ));} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace() ;} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private"at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)at java.lang.reflect.Field.set(Unknown Source)at com.app.T1.main(T1.java:20)

程序崩溃,原因是:id 这个属性的是 private 私有的,不能修改它的值。

改进:

添加 idField.setAccessible( true );

完整的代码为:

package com.app;import java.lang.reflect.Field;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//创建实例Object person = class1.newInstance();//获得id 属性Field idField = 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 (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace() ;} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

100

实战3:综合训练,反射操作属性和方法

package com.app;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//创建实例Object person = class1.newInstance();//获得id 属性Field idField = class1.getDeclaredField( "id" ) ;//打破封装  实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  idField.setAccessible( true );//给id 属性赋值idField.set(  person , "100") ;//获取 setName() 方法Method setName = class1.getDeclaredMethod( "setName", String.class ) ;//打破封装 setName.setAccessible( true );//调用setName 方法。setName.invoke( person , "jack" ) ;//获取name 字段Field nameField = class1.getDeclaredField( "name" ) ;//打破封装 nameField.setAccessible( true );//打印 person 的 id 属性值String id_ = (String) idField.get( person ) ;System.out.println( "id: " + id_ );//打印 person 的 name 属性值String name_ = ( String)nameField.get( person ) ;System.out.println( "name: " + name_ );//获取 getName 方法Method getName = class1.getDeclaredMethod( "getName" ) ;//打破封装 getName.setAccessible( true );//执行getName方法,并且接收返回值String name_2 = (String) getName.invoke( person  ) ;System.out.println( "name2: " + name_2 );} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace() ;} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

id: 100
name: jack
name2: jack

实战4:静态属性、静态方法调用

定义 Util 类

package com.app;public class Util {public static String name = "json" ;/*** 没有返回值,没有参数*/public static void getTips(){System.out.println( "执行了---------1111");}/*** 有返回值,没有参数*/public static String getTip(){System.out.println( "执行了---------2222");return "tip2" ;}/*** 没有返回值,有参数* @param name*/public static void getTip( String name ){System.out.println( "执行了---------3333 参数: " + name );}/*** 有返回值,有参数* @param id* @return*/public static String getTip( int id ){System.out.println( "执行了---------4444 参数: " + id );if ( id == 0 ){return "tip1 444 --1 " ;}else{return "tip1 444 --2" ;}}}

完整小例子:

package com.app;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Util");//获取 nameField 属性Field nameField = class1.getDeclaredField( "name" ) ;//获取 nameField 的值String name_ = (String) nameField.get( nameField ) ;//输出值System.out.println( name_ );//没有返回值,没有参数Method getTipMethod1 = class1.getDeclaredMethod( "getTips"  ) ; getTipMethod1.invoke( null  ) ;//有返回值,没有参数Method getTipMethod2 = class1.getDeclaredMethod( "getTip"  ) ; String result_2 = (String) getTipMethod2.invoke( null  ) ;System.out.println( "返回值: "+ result_2 );//没有返回值,有参数Method getTipMethod3 = class1.getDeclaredMethod( "getTip" , String.class  ) ; String result_3 = (String) getTipMethod3.invoke( null , "第三个方法"  ) ;System.out.println( "返回值: "+ result_3 );//有返回值,有参数Method getTipMethod4 = class1.getDeclaredMethod( "getTip" , int.class ) ; String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;System.out.println( "返回值: "+ result_4 );} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace() ;} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果:

json
执行了---------1111
执行了---------2222
返回值: tip2
执行了---------3333 参数: 第三个方法
返回值: null
执行了---------4444 参数: 1
返回值: tip1 444 --2

当参数是 int 类型 和 Integer 类型,反射获取方法不一样

  • 当参数是 int 类型时
    /*** 没有返回值,有参数* @param id*/public static void getTip( int id ){}

获取方法的时候需要用:int.class。不能使用 Integer.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , int.class ) ;
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "返回值: "+ result_4 );
  • 当参数是 Integer类型时
    /*** 没有返回值,有参数* @param id*/public static void getTip( Integer id ){}

获取方法的时候需要用:Integer .class。不能使用 int.class. 会报错。

Method getTipMethod4 = class.getDeclaredMethod( "getTip" , Integer.class ) ;
String result_4 = (String) getTipMethod4.invoke( null  , 1 ) ;
System.out.println( "返回值: "+ result_4 );

创建对象实例

Person 类

package com.app;public class Person{private String id ;private String name ;//构造函数1public Person( ){System.out.println( "构造函数  无参" );}//构造函数2public Person( String id ){this.id = id ;System.out.println( "构造函数 id : " + id );}//构造函数3public Person( String id  , String name ){this.id = id ;this.name = name ;System.out.println( "构造函数 id : " + id  + " name: " + name );}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

创建实例实战

package com.app;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class T1 {public static void main(String[] args) {try {//创建类Class<?> class1 = Class.forName("com.app.Person");//无参构造函数Object object = class1.newInstance() ;//有参构造函数:一个参数Constructor<?> constructor =  class1.getDeclaredConstructor( String.class ) ;constructor.newInstance( "1000" ) ;//有参构造函数:二个参数Constructor<?> constructor2 =  class1.getDeclaredConstructor( String.class , String.class ) ;constructor2.newInstance( "1001" , "jack" ) ;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace() ;} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

运行结果

构造函数  无参
构造函数 id : 1000
构造函数 id : 1001 name: jack

总结

  • Class类提供了四个public方法,用于获取某个类的构造方法。
Constructor getConstructor(Class[] params)     根据构造函数的参数,返回一个具体的具有public属性的构造函数
Constructor getConstructors()     返回所有具有public属性的构造函数数组
Constructor getDeclaredConstructor(Class[] params)     根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
Constructor getDeclaredConstructors()    返回该类中所有的构造函数数组(不分public和非public属性)
  • 四种获取成员方法的方法
Method getMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的具有public属性的方法
Method[] getMethods()    返回所有具有public属性的方法数组
Method getDeclaredMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的方法(不分public和非public属性)
Method[] getDeclaredMethods()    返回该类中的所有的方法数组(不分public和非public属性)
  • 四种获取成员属性的方法
Field getField(String name)    根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields()    返回具有public属性的成员变量的数组
Field getDeclaredField(String name)    根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredField()    返回所有成员变量组成的数组(不分public和非public属性)

Java 反射 使用总结相关推荐

  1. Java 反射 (快速了解反射)

    反射的概念 JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java ...

  2. java反射最佳实践,java反射性能测试分析

    java反射性能测试分析 java有别于其他编程语言而让我着迷的特性有很多,其中最喜欢的是接口设计,他让我们设计的东西具有美感.同样反射也是我比较喜欢的一个特性,他让程序自动运行,动态加载成为了可能, ...

  3. java 获取 反射 方法 名_乐字节Java反射之一:反射概念与获取反射源头Class

    一.Java反射机制概念 "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言",如Python, Ruby是动态语言:显然C++,Java,C#不是动态语言,但是JAV ...

  4. Java反射以及应用

    需求:需要通过反射动态获取类的字段类型,然后做特殊处理 Java反射getDeclaredField和getField的区别 getDeclaredFiled 只能获取类本身的属性成员(包括私有.共有 ...

  5. java反射用在哪里_Java反射

    昨天去参加比赛了,所以没有进行博客迁移.人生中的第一场健体比赛,虽然没得奖,但是收获和带来的思考颇丰.意外地进入了男子B组(174以上)的半决赛,然后在半决赛的时候还被裁判员点名出去单独比较,这个很让 ...

  6. Java反射(详述版)

    一.什么是反射? 我们先来看一个例子: package venus; public class Student {public String name;public Student(){System. ...

  7. java 反射 动态代理

    在上一篇文章中介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大 ...

  8. Java反射 - 私有字段和方法

    尽管普遍认为通过Java Reflection可以访问其他类的私有字段和方法. 这并不困难. 这在单元测试中可以非常方便. 本文将告诉你如何. 访问私有字段 要访问私有字段,您需要调用Class.ge ...

  9. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  10. Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法...

    Struts2中action接收参数的三种方法及ModelDriven跟Preparable接口结合JAVA反射机制的灵活用法 www.MyException.Cn   发布于:2012-09-15 ...

最新文章

  1. 【ACM】杭电OJ 2005
  2. 贝叶斯推断方法 —— 从经验知识到推断未知
  3. 史上最全 Java 多线程面试题及答案
  4. hdu2824(2009多校第一场) 线性筛法求欧拉函数
  5. 处理js事件时,获取键盘数字注意
  6. 【通知】深度学习之人脸图像算法重印,欢迎读者支持!
  7. MySQL学习笔记03-MySQL的安装 .
  8. 前端学习(3350):数组方法的运用和数值join
  9. kubectl apply -f_新车 | 新款捷豹F-PACE登陆广州车展!内外提升十分明显
  10. 大型Web 网站 Asp.net Session过期你怎么办
  11. 【排错】exchange2013不能显示所有OU
  12. BCH/BCHABC/BCHSV分叉后重放机制小结
  13. matlab计算纹波电压,如何估算开关电源纹波电压?
  14. 机器学习10大经典算法详解
  15. 如何用课件制作工具演示长方形展开动画
  16. 谷歌学术用publish-or-perish来对引用量排序
  17. requests.exceptions.SSLError: HTTPSConnectionPool(host=‘edith.xiaohongshu.com‘, port=443): Max retri
  18. HikariPool-1 - Exception during pool initialization.的解决方法
  19. Keras LSTM对20 Newsgroups数据集进行分类
  20. matlab mex入门简介

热门文章

  1. python爬取app中的音频_Python爬取抖音APP,只需要十行代码
  2. mysql varchar最多可以存多少汉字_MySql的这几个坑你踩过没?真是防不胜防!
  3. 四十七、微信小程序开发页面结构WXML
  4. 三十八、网络通信Socket模块实现文件传输
  5. torch中的topk()函数
  6. selenium容易忽视的知识点
  7. linux cat代码,linux cat命令(示例代码)
  8. Mysql安装两种方法
  9. 实录 | 平安人寿资深算法工程师谢舒翼:智能问答系统探索与实践
  10. 牛客网 最短路 Floyd算法 Dijkstra算法 Java大数