1.什么是java反射

java的反射机制是指在运行状态中,

对于任意一个类,都能知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个属性和方法;

这种动态获取的类的信息,和动态调用对象的方法的功能就是反射机制。

2.反射的作用

在运行时,构造任意一个类的对象

在运行时,判断任意一个类的完整结构,比如属性,方法,内部类,实现接口等

在运行时,判断任意一个对象所属的类

在运行时,调用任意一个对象的属性和方法

在运行时,生成动态代理

3.关键类

Class类是反射类的基础,在java.lang包下,有四种方式可以获取Class类对象

Field,Method,Constructor 都在java.lang.reflect包下

Field是获取Class对象中的属性

Method是获取Class对象中的方法(不包含构造方法)

Construct是获取Class对象中的构造函数

4.测试代码

四种获取Class类的方法:

     Person p = new Person();// 方法一 : 调用运行时类的.class属性Class c1 = Person.class;System.out.println("方法一 : 调用运行时类的.class属性: "+c1.toString());// 方法二 : 通过运行时类的对象,调用getClass()方法Class c2 = p.getClass();System.out.println("方法二 : 通过运行时类的对象,调用getClass()方法: "+c2.toString());// 方法三 : 调用Class的静态方法forNameClass c3 = Class.forName("reflect.Person");System.out.println("方法三 : 调用Class的静态方法forName: "+c3.toString());// 方法四 :通过类的加载器ClassLoader classLoader = Person.class.getClassLoader();Class c4 = classLoader.loadClass("reflect.Person");System.out.println("方法四 :通过类的加载器: "+c4.toString());

运行结果是:

方法一 : 调用运行时类的.class属性: class reflect.Person
方法二 : 通过运行时类的对象,调用getClass()方法: class reflect.Person
方法三 : 调用Class的静态方法forName: class reflect.Person
方法四 :通过类的加载器: class reflect.Person

获取Class中的构造函数:

     System.out.println("getConstructors为获取类的public的构造方法 ");Constructor[] constructors1 = c1.getConstructors();for(int i=0;i<constructors1.length;i++){System.out.println("constructors ["+i+"] :"+constructors1[i]);}
     Class<? extends Object> c1 = Person.class;//调用指定的构造器创建运行时类的对象//我们指定public类型的构造方法Person(String name)来创建对象Constructor<?> constructor = c1.getDeclaredConstructor(String.class);Person person = (Person) constructor.newInstance("xl");System.out.println("调用指定的构造器(public)创建运行时类的对象 --person: "+person);      //我们指定private类型的构造方法Person(String name)来创建对象constructor = c1.getDeclaredConstructor(String.class,String.class);constructor.setAccessible(true);person = (Person) constructor.newInstance("xl2","15");System.out.println("调用指定的构造器(private)创建运行时类的对象 --person: "+person);

运行结果是:

getConstructors为获取类的public的构造方法
constructors [0] :public reflect.Person(java.lang.String)
constructors [1] :public reflect.Person()
调用指定的构造器(public)创建运行时类的对象 --person: [name : xl ][age : null]
调用指定的构造器(private)创建运行时类的对象 --person: [name : xl2 ][age : 15]

获取Class中全部Method:

     Person person = new Person();Class<? extends Object> c1 = person.getClass();//getMethods此方法为获取类的public方法,包括父类的public方法System.out.println("getMethods此方法为获取类的public方法,包括父类的public方法 ");Method[] method1 = c1.getMethods();      for(int i=0;i<method1.length;i++){System.out.println("method1 ["+i+"] :"+method1[i]);}//getDeclaredMethods此方法为获取类本身声明的所有方法,包括privateSystem.out.println("getDeclaredMethods此方法为获取类本身声明的所有方法,包括private ");Method[] method2 = c1.getDeclaredMethods();      for(int i=0;i<method2.length;i++){System.out.println("method2 ["+i+"] :"+method2[i]);}//1.对private类型的方法进行操作System.out.println("getDeclaredMethod 方法获取类本身声明的方法,包括private类型的方法,以setName(私有)方法为例:");Method m1 = c1.getDeclaredMethod("setName", String.class);m1.setAccessible(true);System.out.println("修改前的person:"+person);m1.invoke(person, "xl");System.out.println("修改后的person:"+person);

运行结果是:

getMethods此方法为获取类的public方法,包括父类的public方法
method1 [0] :public java.lang.String reflect.Person.toString()
method1 [1] :public java.lang.String reflect.Person.getName()
method1 [2] :public void reflect.Person.setName(java.lang.String)
method1 [3] :public void reflect.Person.setAge(java.lang.String)
method1 [4] :public java.lang.String reflect.Person.getAge()
method1 [5] :public final void java.lang.Object.wait() throws java.lang.InterruptedException
method1 [6] :public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method1 [7] :public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
method1 [8] :public boolean java.lang.Object.equals(java.lang.Object)
method1 [9] :public native int java.lang.Object.hashCode()
method1 [10] :public final native java.lang.Class java.lang.Object.getClass()
method1 [11] :public final native void java.lang.Object.notify()
method1 [12] :public final native void java.lang.Object.notifyAll()
getDeclaredMethods此方法为获取类本身声明的所有方法,包括private
method2 [0] :public java.lang.String reflect.Person.toString()
method2 [1] :public java.lang.String reflect.Person.getName()
method2 [2] :public void reflect.Person.setName(java.lang.String)
method2 [3] :void reflect.Person.getSex()
method2 [4] :public void reflect.Person.setAge(java.lang.String)
method2 [5] :public java.lang.String reflect.Person.getAge()
getDeclaredMethod 方法获取类本身声明的方法,包括private类型的方法,以setName(私有)方法为例:
修改前的person:[name : null ][age : null]
修改后的person:[name : xl ][age : null]

获取Class类中Field

     Class<? extends Object> c1 = Person.class;System.out.println("getFields此方法为获取类的public属性,包括父类的public属性 ");Field[] field1 = c1.getFields();     for(int i=0;i<field1.length;i++){System.out.println("field1 ["+i+"] :"+field1[i]);}System.out.println("getDeclaredFields此方法为获取类的本身声明的所有属性,包括private ");Field[] field2 = c1.getDeclaredFields();     for(int i=0;i<field2.length;i++){System.out.println("field2 ["+i+"] :"+field2[i]);}

运行结果是:

getFields此方法为获取类的public属性,包括父类的public属性
field1 [0] :public java.lang.String reflect.Person.age
getDeclaredFields此方法为获取类的本身声明的所有属性,包括private
field2 [0] :private java.lang.String reflect.Person.name
field2 [1] :public java.lang.String reflect.Person.age

对Field进行处理:

     Person person = new Person("zj");Class<? extends Object> c1 = person.getClass();System.out.println("对public类型的属性进行操作,以类本身的private属性name为例");Field f1 = c1.getDeclaredField("name");f1.setAccessible(true);String name = (String)f1.get(person);System.out.println("修改前person对象name:"+name);f1.set(person, "xl");name = (String)f1.get(person);System.out.println("修改后person对象的name:"+name);

运行结果是:

对public类型的属性进行操作,以类本身的private属性name为例
修改前person对象name:zj
修改后person对象的name:xl

还有一些对内部类、接口进行的一些操作,这里就不一一列举了。

5.用例:重写Object的toString方法

public class Person {private String name;private String age;public Person(String name, String age) {this.name = name;this.age = age;}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;}@Overridepublic String toString() {StringBuffer result = new StringBuffer();try {// 1.获取Class类Class<? extends Object> clazz = this.getClass();// 2.获取全部属性Field [] fields = clazz.getDeclaredFields();for (Field field : fields) {String fieldName = field.getName();// 3.除去序列化属性if ("serialVersionUID".equals(fieldName)) {continue;}// 4.拼接方法名String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1, fieldName.length());Method method;Object resultObj;// 5.通过方法名获取方法method = clazz.getMethod(methodName);// 6.get方法没有参数,直接属性对应的值resultObj = method.invoke(this);if (resultObj != null && !"".equals(resultObj)) {result.append("[").append(fieldName).append("]").append(resultObj).append(" ");}}} catch (SecurityException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException| InvocationTargetException e) {e.printStackTrace();}return result.toString();}
}
public class ReflectTest {public static void main(String[] args){Person person = new Person("xl","28");System.out.println(person.toString());}
}

运行结果是:

[name]xl [age]28 

参考:

java核心技术之reflect(一):一个系统学习reflect的Demo(精)

JAVA深入研究——Method的Invoke方法

JAVA Reflect反射详解相关推荐

  1. java 7 反射_【7】java 反射详解

    [7]java 反射详解 获取Class对象的方式: 1. Class.forName("全类名"); 将字节码加载进内存,返回Class对象,多用于配置文件,将类名定义在配置文件 ...

  2. Java :反射详解

    Java 反射详解 目录 Java 反射详解 1.什么是反射? 2.反射能做什么? 3.反射的具体实现 4.根据反射获取父类属性 4.反射总结 1.什么是反射? Java反射就是在运行状态中,对于任意 ...

  3. 4.6 W 字总结!Java 11—Java 17特性详解

    作者 | 民工哥技术之路 来源 | https://mp.weixin.qq.com/s/SVleHYFQeePNT7q67UoL4Q Java 11 特性详解 基于嵌套的访问控制 与 Java 语言 ...

  4. Java注解(Annotation)详解

    转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...

  5. 代码检查规则:Java语言案例详解

    本节课程为<代码检查规则:Java语言案例详解>, 通常情况下Java的代码检查规则可以分为以下十类: 接下来,让我们具体来看看每个分类的内容. 一.源文件规范 该类规范主要从文件名.文件 ...

  6. Proxy和Reflect内容详解

    ES6中的Proxy和Reflect内容详解 监听对象的操作 我们先来看一个需求:有一个对象,我们希望监听这个对象中的属性被设置或获取的过程 通过我们前面所学的知识,能不能做到这一点呢? 其实是可以的 ...

  7. 李兴华java8教程_李兴华Java培训系列详解20套视频教程下载

    李兴华Java培训系列详解20套视频教程下载 教程介绍: 李兴华Java培训系列详解20套视频教程分别对Oracle.Java8.JavaScript.XML.AJAX.jQuery.HTML5.St ...

  8. JAVA动态代理详解

    JAVA动态代理详解 问题 1:什么是静态代理,动态代理? 2:动态代理的好处? 什么是静态代理 以生活中例子来看,我作为某某品牌面膜的北京区代理,我替厂家卖面膜,我属于代理,厂家属于委托方. 联系到 ...

  9. Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例

    Java 泛型(generics)详解及代码示例.Java 类型通配符详解及代码示例 - 概念 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制 ...

  10. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

最新文章

  1. 前端如何查看音频的长度_重学前端基础:如何查看文档对象的所有属性?如何文档查找节点?...
  2. Java的小实验——各种测试以及说明
  3. 什么样的文献有html阅读,有关html的参考文献
  4. JAVA 连接MYSQL数据库操作
  5. java如何获取明天的时间_java获取各种格式的时间,获取昨天明天日期,获取一天的开始结束时间...
  6. Logminer实战
  7. naarray查询 swift_Swift 4最全的新特性详细解析(推荐)
  8. python三维数据图_matplotlib中三维数据的热图
  9. 论文浅尝 | 利用图 Transformer 实现基于知识图谱的文本生成
  10. linux是否安装java环境,linux是否安装java环境
  11. dbcp连接池配置详解_重学MySQL:事务与连接池,一文详解带你搞懂
  12. 动手学深度学习Pytorch Task08
  13. 函数式编程能否支持更高效的区块链基础设施?
  14. 微型计算机技术试题,《微型计算机技术》试题库
  15. 华为网络设备-访问控制列表配置实验
  16. mumu模拟器显示服务器出错,用mumu模拟器显示错误代码
  17. 选型笔记之二极管选型
  18. cat3速度 rj45_RJ45公对母延长线 网络线纯铜cat5宽带5类0.3米长线
  19. 设计模式(三)代理设计模式
  20. IE浏览器下载文件名出现中文乱码问题解决

热门文章

  1. PHP accesstoken失效,微信开发-ACCESS TOKEN 过期失效解决方案
  2. 在Windows 10下配置 DirectX11 + Visual Studio 2017开发环境
  3. mysql 多数据源配置文件_Spring+MyBatis多数据源配置实现
  4. c语言万年历方案论证,C语言编写方案-万年历分析.doc
  5. 最全最新cpu显卡天梯图_2019桌面级显卡排行_2019年2月最新CPU天梯图 桌面级处理器天梯图...
  6. oracle12c cdb修改,Oracle 12c 配置和修改 CDB 和 PDB 参数
  7. 经典语录-让心灵不再寂寞
  8. OSChina 周三乱弹 ——你是有多寂寞啊,看光头强都……
  9. 改造:Ueditor编辑器插入外链视频支持手机播放和上传本地音乐
  10. win7计算机自动关机设置在哪里设置方法,win7系统怎么设置每天自动关机|win7创建定时关机计划的方法...