反射

目录介绍

1.反射概述

1.1 反射概述

1.2 获取class文件对象的三种方式

1.3 反射常用的方法介绍

1.4 反射的定义

1.5 反射的组成

1.6 反射的作用有哪些

2.反射的相关使用

2.1.1 通过反射获取无参构造方法并使用

2.1.2 通过反射获取带参构造方法并使用

2.1.3 通过反射获取私有构造方法并使用

2.1.4 通过反射获取成员变量并使用

2.1.5 通过反射获取无参无返回值成员方法并使用

2.1.6 通过反射获取带参无返回值成员方法并使用

2.1.7 通过反射获取带参带返回值成员方法并使用

2.1.8 通过反射获取无参带返回值成员方法并使用

3.相关知识点

3.1.1 设置setAccessible(true)暴力访问权限

3.1.2 获取Filed两个方法的区别

3.1.3 获取Field的类型

3.1.4 Method获取方法名,获取方法参数

3.1.5 Method方法的invoke()方法执行

关于链接

1.技术博客汇总

2.开源项目汇总

3.生活博客汇总

4.喜马拉雅音频汇总

5.程序员聊天笔记汇总

5.其他汇总

0.问题答疑

0.1 被反射的类是否一定需要无参构造方法?为什么?

0.2 反射的使用有什么优势和劣势?为什么说反射可以降低耦合?

0.3 反射比较损耗性能,为什么这样说?能否通过案例对比说明反射机制损耗性能……

0.4 反射是一种具有与类进行动态交互能力的一种机制,为什么要强调动态交互呢?

0.5 Java反射中的setAccessible()方法是否破坏了类的访问规则

0.2 反射的使用有什么优势和劣势?

射的初衷不是方便你去创建一个对象,而是让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力。

0.4 反射是一种具有与类进行动态交互能力的一种机制,为什么要强调动态交互呢

动态加载,也就是在运行的时候才会加载,而不是在编译的时候,在需要的时候才进行加载获取,或者说你可以在任何时候加载一个不存在的类到内存中,然后进行各种交互,或者获取一个没有公开的类的所有信息,换句话说,开发者可以随时随意的利用反射的这种机制动态进行一些特殊的事情。

1.反射概述

1.1 反射概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

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

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。

而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象

1.2 获取class文件对象的三种方式

1.2.1 这三种方式为:

a:Object类的getClass()方法

b:静态属性class

c:Class类中静态方法forName()

1.2.2 第一种方法【Object类的getClass()方法】

1.在内存中新建一个Person的实例,对象p对这个内存地址进行引用

2.对象p调用getClass()返回对象p所对应的Class对

3.调用newInstance()方法让Class对象在内存中创建对应的实例,并且让p2引用实例的内存地址

1.2.3 第二种方法【静态属性class】

1.获取指定类型的Class对象,这里是Person

2.调用newInstance()方法在让Class对象在内存中创建对应的实例,并且让p引用实例的内存地址

1.2.4 第三种方法【Class类中静态方法forName()】

1.通过JVM查找并加载指定的类(上面的代码指定加载了com.fanshe包中的Person类)

2.调用newInstance()方法让加载完的类在内存中创建对应的实例,并把实例赋值给p

注意:如果找不到时,它会抛出 ClassNotFoundException 这个异常,这个很好理解,因为如果查找的类没有在 JVM 中加载的话,自然要告诉开发者。

1.3 通过反射获取无参构造方法并使用

A:获取所有构造方法

public Constructor[] getConstructors()

public Constructor[] getDeclaredConstructors()

B:获取单个构造方法

public Constructor getConstructor(Class... parameterTypes)

public Constructor getDeclaredConstructor(Class... parameterTypes)

方法关键字

getDeclareMethods() 获取所有的方法

getReturnType() 获取方法的返回值类型

getParameterTypes() 获取方法的传入参数类型

getDeclareMethod("方法名,参数类型.class,....") 获得特定的方法

构造方法关键字

getDeclaredConstructors() 获取所有的构造方法

getDeclaredConstructors(参数类型.class,....) 获取特定的构造方法

成员变量

getDeclaredFields 获取所有成员变量

getDeclaredField(参数类型.class,....) 获取特定的成员变量

父类和父接口

getSuperclass() 获取某类的父类

getInterfaces() 获取某类实现的接口

1.4 反射的定义

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

1.5 反射的组成

由于反射最终也必须有类参与,因此反射的组成一般有下面几个方面组成:

1.java.lang.Class.java:类对象;

2.java.lang.reflect.Constructor.java:类的构造器对象;

3.java.lang.reflect.Method.java:类的方法对象;

4.java.lang.reflect.Field.java:类的属性对象;

反射中类的加载过程

根据虚拟机的工作原理,一般情况下,类需要经过:加载->验证->准备->解析->初始化->使用->卸载这个过程,如果需要反射的类没有在内存中,那么首先会经过加载这个过程,并在在内存中生成一个class对象,有了这个class对象的引用,就可以发挥开发者的想象力,做自己想做的事情了。

1.6 反射的作用有哪些

前面只是说了反射是一种具有与Java类进行动态交互能力的一种机制,在Java和Android开发中,一般情况下下面几种场景会用到反射机制.

需要访问隐藏属性或者调用方法改变程序原来的逻辑,这个在开发中很常见的,由于一些原因,系统并没有开放一些接口出来,这个时候利用反射是一个有效的解决方法

自定义注解,注解就是在运行时利用反射机制来获取的。

在开发中动态加载类,比如在Android中的动态加载解决65k问题等等,模块化和插件化都离不开反射,离开了反射寸步难行。

2.反射的相关使用

2.1.4 通过反射获取成员变量[包含私有]并使用

2.1.5 通过反射获取无参无返回值成员方法[包含私有]并使用

2.1.6 通过反射获取带参无返回值成员方法并使用

2.1.7 通过反射获取带参带返回值成员方法并使用

3.相关知识点

3.1.1 设置.setAccessible(true)暴力访问权限

一般情况下,我们并不能对类的私有字段进行操作,利用反射也不例外,但有的时候,例如要序列化的时候,我们又必须有能力去处理这些字段,这时候,我们就需要调用AccessibleObject上的setAccessible()方法来允许这种访问,而由于反射类中的Field,Method和Constructor继承自AccessibleObject,因此,通过在这些类上调用setAccessible()方法,我们可以实现对这些字段的操作。

3.1.2 获取Filed两个方法的区别

两者的区别就是 getDeclaredField() 获取的是 Class 中被 private 修饰的属性。 getField() 方法获取的是非私有属性,并且 getField() 在当前 Class 获取不到时会向祖先类获取。

3.1.3 获取Field的类型

可以看到 getGenericType() 确实把泛型都打印出来了,它比 getType() 返回的内容更详细。

3.1.4 Method获取方法名,获取方法参数

3.1.5 Method方法的invoke()方法执行

Method 调用 invoke() 的时候,存在许多细节:

invoke() 方法中第一个参数 Object 实质上是 Method 所依附的 Class 对应的类的实例,如果这个方法是一个静态方法,那么 ojb 为 null,后面的可变参数 Object 对应的自然就是参数。

invoke() 返回的对象是 Object,所以实际上执行的时候要进行强制转换。

在对Method调用invoke()的时候,如果方法本身会抛出异常,那么这个异常就会经过包装,由Method统一抛InvocationTargetException。而通过InvocationTargetException.getCause() 可以获取真正的异常。

本文作者:潇湘剑雨

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

Java反射详细介绍的更多相关文章

  1. java agent 详细介绍 -javaagent参数

    java agent 详细介绍 简介 java agent是java命令的一个参数.参数 javaagent 可以用于指定一个 jar 包,并且对该 java 包有2个要求: 这个 jar 包的MAN ...

  2. Java 反射机制介绍

    参考文章:http://www.cnblogs.com/skywang12345/p/3345205.html Java 反射机制.通俗来讲呢,就是在运行状态中,我们可以根据“类的部分已经的信息”来还 ...

  3. JAVA HashMap详细介绍和示例

    http://www.jb51.net/article/42769.htm 我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.   第1部分 HashMa ...

  4. Java反射机制介绍

    1. 文档概述 Java反射是Java被视为动态(或准动态)语言的一个关键性质,Java反射机制容许程序在运行时加载.探知.使用编译期间完全未知的classes.换言之,Java可以加载一个运行时才得 ...

  5. Android 插件化开发(一):Java 反射技术介绍

    写在前面:学习插件化开发推荐书籍<Android 插件化开发指南>,本系列博客所整理知识部分内容出自此书. 在之前的项目架构的博文中,我们提到了项目插件化架构,提到插件化架构不得不提的到J ...

  6. Java linkedList详细介绍及使用示例

    ①LinkedList简单介绍 是一个继承于AbstractSequentialList的双向链表.它可以被当成堆栈.队列或双端队列进行操作. 实现了List接口,能对它进行队列操作. 实现了Dequ ...

  7. Java高精度学习第三弹——ACM中使用JAVA的详细介绍

    Chapter I. Java的优缺点各种书上都有,这里只说说用Java做ACM-ICPC的特点: (1) 最明显的好处是,学会Java,可以参加Java Challenge . (2) 对于熟悉C/ ...

  8. Java ArrayList详细介绍和使用示例

    ①对ArrayList的整体认识 ArrayList是一个数组队列,相当于动态数组.与Java中的数组相比,它的容量能动态增长.它继承了AbstractList,实现了List,RandomAcces ...

  9. Java Vertor详细介绍和使用示例

    ①对Vector有个整体认识 Vector是向量类,继承于AbstractList,实现了List,RandomAccess,Clonable这些接口. Vector继承于AbstractList,实 ...

随机推荐

  1. ECMAScript 6,es6 get和set的区别

    前言:ECMAScript 6是什么 一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? 要讲清楚这个问题,需要回顾历史.1996 年 11 月,JavaScript ...

  2. java中封装,继承,多态,接口学习总结

    ### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...

  3. 典型的MVC架构图

    通常,当使用MVC时,应用程序中的每个逻辑部分都有一个单一的控制器.在这些控制器的前面还有一个Router:这是一个看门人,用于确定用户请求的内容,以便应用程序满足用户需要.常用php的mvc框架:Y ...

  4. 给listview添加长时间点击事件(完成删除操作)

    出现的问题是:当长时间点击listview的时候,触发长时间点击事件的同时也会触发点击事件,处理的办法是在长时间点击事件中加上return true:这样就可以很好的解决了. 给listview天机长 ...

  5. YII基础二

    YII多表关联查询 ->select("{{%relation_detail}}.name") ->from("{{%user}}") ->l ...

  6. 【python实现卷积神经网络】定义训练和测试过程

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  7. Linux/UNIX 下 “command not found” 原因分析及解决

    在使用 Linux/UNIX 时,会经常遇到 "command not found" 的错误,就如提示的信息,Linux /UNIX 没有找到该命令.原因无外乎你命令拼写错误或 L ...

  8. 多线程高并发编程(4) -- ReentrantReadWriteLock读写锁源码分析

    背景: ReentrantReadWriteLock把锁进行了细化,分为了写锁和读锁,即独占锁和共享锁.独占锁即当前所有线程只有一个可以成功获取到锁对资源进行修改操作,共享锁是可以一起对资源信息进行查 ...

  9. stand up meeting 1/15/2016 && work of weekend 1/16/2016~1/17/2016

    part 组员                工作              工作耗时/h 明日计划 工作耗时/h    UI 冯晓云  组内对生词卡片又重新进行了讨论:准备最后的发布和整个开发的整理 ...

  10. C++ 11 +,开坑。

    最近换新工作了.工作中需要用到高端的c++11的一些操作,至于我后面又plus一下还是因为可能是c++14或者17中提供的一些操作.反正都是c++11以及之后的一些特性. 首先,今天看一下关于函数模板 ...