谁能给我讲一讲Java中反射机制?

Java的反射就是在运行时通过访问class文件来动态的执行某些方法。


一、什么是反射机制

简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

二、哪里用到反射机制

有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在jdbc时用过一行代码,Class.forName(com.mysql.jdbc.Driver.class).newInstance();原来这就是反射,现在很多开框架都用到反射机制,hibernate、struts都是用反射机制实现的。

三、反射机制的优点与缺点

为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,静态编译:在编译时确定类型,绑定对象,即通过。

动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。

一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中

它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。


没人请,自己搬小板凳过来的,您的问题什么事Java反射机制?

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


java的反射机制主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。


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

以上来自百度百科。

我之前写过一篇关于Java创建对象的文章,里面提到了两种Java的反射机制。

第一种:利用

Class.newInstance

方式创建对象

第二种:利用

Constructor.newInstance

方式创建对象

Class.newInstance你内部也是调用了Constructor.newInstance。所以大多数的开源框架都会使用Constructor来实现反射。

希望对你有用!


Java反射的概念

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

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

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

反射的作用

我们都知道程序员编写的Java代码必须编译成.class文件才能在JVM中运行,如何不符合JVM的规范,则会在编译期间报错。那么反射的意思和反编译差不多,就是根据

.class

文件获取这个类的所有属性和方法,且可以调用它的方法。

正常方式:通过完整的类名&;通过new实例化&;取得实例化对象

反射方式:实例化对象&;getClass()方法&;通过完整的类名

示例

创建一个用于测试的类:

TestReflect.java

获取类的三种方式:

获取类的所有属性:

获取类的所有方法:

获取所有的构造方法:

动态调用方法:

反射的应用场景

Spring框架中的IoC:控制反转,依赖注入

通过反射机制获取注解信息

逆向代码,反编译

动态代理

AOP

...

以上就是Java反射的基础入门知识,希望对题主的问答有所帮助~


在学习Java反射之前,先让我们看看这几个概念。

01.解释型语言和编译型语言

解释型语言:不需要编译,在运行的时候逐行翻译解释;修改代码时可以直接修改,可以快速部署,不过性能上会比编译型语言稍差;比如JavaScript、Python;

编译型语言:需要通过编译器将源代码编译成机器码才能执行;编译之后如果需要修改代码,在执行之前就需要重新编译。比如C语言;

Java严格来说也是编译型语言,但又介于编译型和解释型之间;Java不直接生成机器码而是生成中间码:编译期间,是将源码交给编译器生成class文件(字节码),这个过程中只做了翻译的工作,并没有把代码放入内存运行;当进入运行期,字节码才被Java虚拟机加载、解释成机器语言并运行。

02.动态语言和静态语言

动态语言:是指程序在运行时可以改变自身结构,在运行时确定数据类型,一个对象是否能执行某操作,只取决于它有没有对应的方法,而不在乎它是否是某种类型的对象;比如JavaScript、Python。

静态语言:相对于动态语言来说,在编译时变量的数据类型就已经确定(使用变量之前必须声明数据类型),在编译时就会进行类型是否匹配;比如C语言、Java;

03.反射的概念

Java反射机制:在运行过程中,对于任意一个类,都能知道其所有的属性和方法;对于任意一个对象,都能调用其属性和方法;这种动态获取类信息和调用对象方法的功能,就是Java反射机制。

既然反射里面有一个“反”字,那么我们先看看何为“正”。

在Java中,要使用一个类中的某个方法,“正向”都是这样的:

那么反向(反射)要如何实现?

两段代码执行的结果是一样的,但是“正向”代码在编译前,就已经明确了要运行的类是什么(ArrayList),而第二段代码,只有在代码运行时,才知道运行的类是java.util.ArrayList。

04.反射的作用

讲到这里,有些同学可能会有疑问:“反射有什么用?我明明都已经知道了要使用的类是ArrayList,我不能直接new一个对象然后执行里面的方法么?”

当然可以!不过很多场景中,在代码运行之前并不知道需要使用哪个类,或者说在运行的时候才决定使用哪个类;

比如有这么一个功能:“调用阿里云的人脸识别API”;这还不简单,参考对方的API文档,很快就能实现。

上线一个月后,领导说:“咱公司开始和腾讯云合作了,人脸识别的接口改一下吧”。

修改上线运行了两个月,领导说:“换回来吧”......

当然有聪明的程序员会想到设置一个开关配置,让开关决定走哪段代码逻辑,如果领导哪天想变成亚马逊云的服务,继续写if-else就好了:

不过还有一种更好的方法:

1.定义一个接口:

2.多个实现类:

3.在调用人脸识别功能的代码中:

如果上面这个例子,你依然觉得在调用方法中做if-else判断,和使用反射实现并没有差太多,但是如果程序员A提供接口,程序员B提供实现,程序员C写客户端呢?

回忆一下JDBC的使用,比如创建一个连接:

其中:

程序员A提供接口:Oracle公司(之前的Sun)提供JDBC标准(接口)。

程序员B提供实现:各个数据库厂商提供针对自家数据库的实现。

程序员C写客户端:我等码农在Java中敲代码访问数据库。

总结一下Java反射的作用:可以设计出更为通用和灵活的架构,很多框架为了保证其通用性,可以根据配置加载不用的类,这时候要用到反射。除此之外:

动态代理:在不改变目标对象方法的情况下对方法进行增强,比如使用AOP拦截某些方法打印日志,这就需要通过反射执行方法中的内容。

注解:利用反射机制,获取注解并执行对应的行为。

05.用反射的用法

上文中我们知道了Java运行期的源文件是class文件(字节码),所以要使用反射,那么就需要获取到字节码文件对象,在Java中,获取字节码文件对象有三种方式:

调用某个类的class属性:类名.class

调用对象的getClass()方法:对象.getClass()

使用Class类中的forName()静态方法:Class.forName(类的全路径),建议使用这种方法

java.lang.reflect类库提供了对反射的支持:

Field:可以使用get和set方法读取和修改对象的属性;

Method:可以使用invoke()方法调用对象中的方法;

Constructor:可以用newInstance()创建新的对象。

06.反射的优缺点

优点:在运行时动态获取类和对象中的内容,极大地提高系统的灵活性和扩展性;夸张一些说,反射是框架设计的灵魂。

缺点:会有一定的性能损耗,JVM无法对这些代码进行优化;破坏类的封装性。

总之,可能大家在平时的开发过程中,感觉自己并没有写过反射相关的代码,但是在我们用到的各种开源框架中,反射无处不在。

我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注;关注我后,可私信发送数字【1】,获取海量学习资料。


原始地址:/yule/14013.html

延伸阅读