反射

目录介绍

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. java 第六周课后作业

    1.定义长度位5的整型数组,输入他们的值,用冒泡排序后输出. Scanner sc = new Scanner(System.in); int[] arr = new int[5]; for (int ...

  2. Linux搜索工具

                                                                Linux搜索工具 Search搜索工具 yum search all vim  ...

  3. Android 启动一个Activity的几种方式

    启动一个Activity的几种方式在Android中我们可以通过下面两种方式来启动一个新的Activity,注意这里是怎么启动,而非启动模式!分为显示启动和隐式启动! 1.显式启动,通过包名来启动,写 ...

  4. Git应用详解第四讲:版本回退的三种方式与stash

    前言 前情提要:Git应用详解第三讲:本地分支的重要操作 git作为一款版本控制工具,其最核心的功能就是版本回退,没有之一.熟悉git版本回退的操作能够让你真真正正地放开手脚去开发,不用小心翼翼,怕一 ...

  5. javascript 入门 之 bootstrap 第一个程序

    <table data-toggle="table"> <thead> <tr> <th>Item ID</th> &l ...

  6. [Python] 字符串加密解密

    1. 最简单的方法是用base64: import base64 s1 = base64.encodestring('hello world') s2 = base64.decodestring(s1 ...

  7. 答好友困惑:Java零基础如何入门,不知道怎么学,迷茫ING

    作者:程序员小跃 几个星期之前,我在知乎上看到一个提问,说是:对于完全没有经验零基础自身的数学底子也很弱学习Java应该怎么学习呢?想着类似的问题我也有过回答,并且反馈还是蛮好的,就参考之前的思路回答 ...

  8. Springboot启动流程简单分析

    springboot启动的类为SpringApplication,执行构造函数初始化属性值后进入run方法: 然后返回ConfigurableApplicationContext(spring应用). ...

  9. CSS3 制作正方体

    一.预备知识 变形属性 2D变形属性 transform:他是css3中的变形属性: 通过transform(变形) 来实现2d 或者3d 转换,其中2d 有,缩放 scale(x, y) ,移动 t ...

  10. JVM 调优之 Eclipse 启动调优实战

    本文是我12年在学习<深入理解Java虚拟机:JVM高级特性与最佳实践>时,做的一个 JVM 简单调优实战笔记,版本都有些过时,不过调优思路和过程还是可以分享给大家参考的. 环境基础配置 ...