java反射机制面试题

java反射机制面试题

1、什么是反射机制?

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

2、java反射机制提供了什么功能?

在运行时能够判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任一对象的方法
在运行时创建新类对象

3、Java反射机制的作用

1)在运行时判断任意一个对象所属的类。
2)在运行时判断任意一个类所具有的成员变量和方法。
3)在运行时任意调用一个对象的方法
4)在运行时构造任意一个类的对象

4、反射的原理是什么

反射是为了能够动态的加载一个类,动态的调用一个方法,动态的访问一个属性等动态要求而设计的。它的出发点就在于JVM会为每个类创建一个java.lang.Class类的实例,通过该对象可以获取这个类的信息,然后通过使用java.lang.reflect包下得API以达到各种动态需求。

5、Class类的含义和作用是什么?

每一个Class类的对象就代表了一种被加载进入JVM的类,它代表了该类的一种信息映射。开发者可以通过3种途径获取到Class对象。

6、哪里用到反射机制?

jdbc中有一行代码:Class.forName(‘com.mysql.jdbc.Driver.class’).newInstance();那个时候只知道生成驱动对象实例,后来才知道,这就是反射,现在

很多框架都用到反射机制,hibernate,struts都是用反射机制实现的。

7、反射机制的优缺点?

静态编译:在编译时确定类型,绑定对象,即通过

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

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

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

java反射机制面试题结束

0

java反射获取属性值

java反射获取属性值其实可以分好多情况

1.考虑安全访问范围内的属性,没有权限访问到的属性不读取

2.不考虑从祖先类继承的属性,只获取当前类属性,包括四类访问权限,private,protect,default,public

3.考虑父类继承过来的属性,包括四类访问权限,private,protect,default,public

0

一文看懂为什么java反射性能慢、效率低

简介

稍微了解Java反射的伙伴都知道,java反射是存在一定的性能损耗的,那为什么使用反射创建类会比直接调用类构造函数创建对象慢呢?

java反射之所以慢,根本原因是编译器没法对反射相关的代码做优化。

我们都知道 Java 代码是需要编译才能在虚拟机里运行的,但其实 Java 的编译期是一段不确定的操作过程。因为它可能是一个前端编译器(如 Javac)把 *.java 文件编译成 *.class 文件的过程;也可能是程序运行期的即时编译器(JIT 编译器,Just In Time Compiler)把字节码文件编译成机器码的过程;还可能是静态提前编译器(AOT 编译器,Ahead Of Time Compiler)直接把 *.java 文件编译成本地机器码的过程。

其中即时编译器(JIT)在运行期的优化过程对于程序运行来说更重要,Java虚拟机在编译阶段的代码优化就在这里进行,由于反射涉及动态解析的类型,因此无法执行某些Java虚拟机优化。因此,反射操作的性能要比非反射操作慢,因此应该避免在对性能敏感的应用程序中频繁使用Java反射来创建对象。

代码测试

结果

使用构造函数创建耗时:35
使用java反射创建耗时:465

扩展

如果确实需要比反射更快的速度,那么可以选择使用ASM或更高级别的库生成字节码。

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。说白了asm是直接通过字节码来修改class文件。

ASM 第一次生成字节码比仅使用反射慢,但是一旦生成了字节码,它便与普通Java代码一样快,并且将由JIT编译器进行优化

我们熟知的CGLIB(Code Generation Library)的底层就是是通过 ASM 来实现的。

在CGLIB生成的代理上调用方法比Java的动态代理要快一些,因为CGLIB为其代理生成字节码,但是创建代理要慢一些。

总结

虽然java反射性能存在一定损耗,但并不是说我们就不该用java反射,到底使不使用java反射,应该根据我们的程序设计需求来决定。

如果你只是根据某些条件或配置文件来使用java反射创建对象,然后接下来就做其它操作(如数据库查询等),那其实java反射损耗的那点性能可以忽略不计。

但如果你想在连续循环中通过反射不断创建大量对象,那这是不可取的。

+6

java反射例子应用理解

一、前言

java反射是一个很好的机制,本文会提供一些java反射例子帮助读者对其有所理解。

类其实也是一种对象,是java.lang.Class类的实例。编译阶段类信息会被编译成.class文件,在类加载阶段,类加载器把.class文件读入JVM内存,生成java.lang.Class对象(这时已经可以通过Class对象查看类信息了),再经过类的连接(验证、准备、解析)与类的初始化阶段后即可使用类对象。我们通常使用的new关键字与反射创建实例时都会触发类初始化。

二、Java反射的常规使用步骤

1、获取目标类的java.lang.Class对象
2、获取目标类的信息(字段、方法、构造器、注解等)
3、生成并操作对象

三、获取目标类的java.lang.Class对象

这个是搞Java必会的基础,面试也常问,主要有三种方法:

注:为方便测试,定义一个User类,类定义如下:

测试

结果

其中,第一种和第二种方法都是直接根据类名获取Class对象,第二种方法具有如下两种优势:

1、编译阶段检查目标类是否存在,更安全;

2、无需调用方法,效率更高;

所以,我们通常推荐使用第二种方式获取Class对象,但是如果在编写程序的时候我们不知道这里需要产生哪个Class对象,只知道有个类名会传入,这种情况我们就只能使用第一种方式去获取Class对象,但这也是反射的精髓,动态而灵活。

四、获取目标类信息

1、获取成员变量信息

  • getFields()——获取所有公有成员变量
  • getField(String name)——获取指定名称的公有成员变量,会抛出NoSuchFieldException异常
  • getDeclaredFields()——获取所有成员变量,不关乎权限
  • getDeclaredFields()——获取指定名称的成员变量,不关乎权限,会抛出NoSuchFieldException异常

测试

结果

2、获取方法以及参数信息

  • getMethods()——获取所有公有方法
  • getMethod(String methodName, Class parameterTypes)——根据方法及形参列表获取公有方法,会抛出NoSuchMethodException异常
  • getDeclaredMethods()——获取所有方法
  • getDeclaredMethod(String methodName, Class parameterTypes)——根据方法及形参列表获取方法,会抛出NoSuchMethodException异常
  • getParameters()——获取所有形参

测试

结果

3、获取构造方法信息,和上面一样

  • getConstructors()——获取所有公有构造器
  • getConstructor(Class parameterTypes)——根据形参列表获取某一公有构造器
  • getDeclaredConstructors()——获取所有构造器
  • getDeclaredConstructor(Class parameterTypes)——根据形参列表获取某一构造器

4、获取注解,关键字为annotation,也是和上面一样

五、使用反射生成并操作对象

1、创建对象,两种方式:

Class对象的newInstance()方法——调用默认构造创建实例
Class对象获取指定Constructor对象,再调用该对象的newInstance()方法

测试

2、调用方法

Method对象的invoke(Object obj, Object args)——其中,第一个参数obj是执行该方法的主调(也就是一个拥有这个方法的对象),后面的arg是调用该方法的实参。

测试

3、修改成员变量值

Field对象的getXXX(Object obj)——obj为拥有该属性的对象,XXX为8种基本类型,代表着成员变量类型,如果成员变量为引用类型,则去掉XXX。
Field对象的setXXX(Object obj, XXX val)——obj同上,val为要设置的值

测试

好了,相信大家应该理解了上面的应用java反射例子了。

有问题欢迎留言指正。

0

java反射机制有什么用?

Java语言有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造,并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

java反射机制有什么用?

在Java环境中,反射机制允许程序在执行时获取某个类自身的定义信息,例如属性和方法等。也可以实现动态创建类的对象、变更属性的内容或执行特定的方法的功能。从而使Java具有动态语言的特性,增强了程序的灵活性和可移植性。

Java反射机制主要用于实现以下功能,看完以下几点相信你会对java反射机制有什么用有清晰的了解。

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

注意:上述功能都是在运行时环境中,而不是在编译时环境中。

代码示例

性能损耗

反射在性能方面会有一定的损耗,用于字段和方法接入时反射要远慢于直接写代码。如果它作为程序运行中相对很少涉及的部分将不会造成影响,因为即使测试最坏情况下的计时图显示的反射操作也只耗用几微秒。

0