Java反射面试总结(一)
什么是反射?
Java的反射是指在程序运行时,对于任意一个类,都可以获取到这个类的所有属性和方法,并能够对其进行操作。通过反射机制,可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松地实现一些复杂的功能,但也会带来一些性能上的损失。
Java反射机制的基本步骤:
- 获取Class对象:通过反射可以动态地获取类对象,即Class对象。Class对象是Java运行时系统中的一个重要概念,每个类都有一个与之对应的Class对象,通过Class对象可以获取类的所有信息。
示例代码:
Class clazz = Class.forName("java.lang.String"); // 获取String类的Class对象
- 创建对象:通过Class对象可以实例化一个具体的对象。
示例代码:
Object obj = clazz.newInstance(); // 实例化一个String对象
- 访问属性:通过反射可以获取和设置对象的属性,包括公共的和私有的。
示例代码:
Field field = clazz.getField("value"); // 获取value属性
Object value = field.get(strObj); // 获取value属性的值
field.set(strObj, newValue); // 设置value属性的值为newValue
- 调用方法:通过反射可以调用对象的方法,包括公共的和私有的。
示例代码:
Method method = clazz.getMethod("substring", int.class, int.class); // 获取substring方法
Object result = method.invoke(strObj, startIndex, endIndex); // 调用substring方法,传递参数startIndex和endIndex
- 执行构造函数:通过反射可以调用对象的构造函数来实例化对象。
示例代码:
Constructor constructor = clazz.getConstructor(String.class); // 获取含有一个String类型参数的构造函数
Object obj = constructor.newInstance("Hello, World!"); // 调用构造函数并实例化对象
Java的反射机制带来了很多便利,但同时也会损失一些性能,在使用时需要慎重考虑其是否真正必要。
反射的应用场景了解么?
像咱们平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景。但是!这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。
这些框架中也大量使用了动态代理,而动态代理的实现也依赖反射。
比如下面是通过 JDK 实现动态代理的示例代码,其中就使用了反射类 Method 来调用指定的方法。
public class DebugInvocationHandler implements InvocationHandler {/*** 代理类中的真实对象*/private final Object target;public DebugInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {System.out.println("before method " + method.getName());Object result = method.invoke(target, args);System.out.println("after method " + method.getName());return result;}
}
另外,像 Java 中的一大利器 注解 的实现也用到了反射。为什么你使用 Spring 的时候 ,一个@Component注解就声明了一个类为 Spring Bean 呢?为什么你通过一个 @Value注解就读取到配置文件中的值呢?究竟是怎么起作用的呢?这些都是因为你可以基于反射分析类,然后获取到类/属性/方法/方法的参数上的注解。你获取到注解之后,就可以做进一步的处理。
反射在Java中是一种高级的语言特性,它允许程序在运行时动态地获取类的信息、访问和操作类的属性和方法等。因此,它的应用场景非常广泛,以下是一些例子:
框架开发:许多框架(如Spring)利用反射获取类的信息和属性,来实现依赖注入、控制反转等功能。
动态代理:利用反射机制来动态生成代码,从而实现对某些对象的代理。
注解解析:通过反射来获取类、方法、字段等的注解信息。
Java序列化:反射机制使得可以在编译时未知的情况下,将对象序列化为字节流,然后再通过反射将字节流转换成对象。
反编译工具:反编译工具利用反射实现对Java代码的分析和探测,可以查看方法、字段的信息以及代码的执行流程等。
总之,反射机制是Java语言中非常有用的一种特性,能够极大地提高程序的可扩展性、灵活性和可维护性。
反射机制的优缺点有哪些?
优点
- 动态性:能够运行时动态获取类的信息,访问和操作类的属性和方法,提高了灵活性;例如可与动态编译结合 Class.forName(‘com.mysql.jdbc.Driver.class’),加载MySQL的驱动类;
- 适应性:反射机制不依赖于具体的硬件、操作系统和JVM,可以应用于任何Java程序中;
- 灵活性:反射机制提供了更灵活的编程方式,可以在不知道具体的类名的情况下,创建对象、调用方法等。
缺点
- 性能问题:使用反射性能较低,需要解析字节码,将内存中的对象进行解析。其解决方案是:通过 setAccessible(true) 关闭JDK的安全检查来提升反射速度;
- 安全问题:反射机制可以访问和修改对象的私有属性和方法,有可能会破坏程序的安全性和稳定性,因此必须谨慎使用;
- 可读性问题:反射机制动态调用方法和属性,代码可读性较差,不容易维护和调试。
总之,优点就是动态获取类信息,操作类的属性和方法们这是核心,缺点无非就是性能、安全和可读性,一定不要死记硬背,要通过原理去理解。
如何获取反射中的Class对象?
- Class.forName(“类的路径”);当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
Class clz = Class.forName("java.lang.String");
- 类名.class。这种方法只适合在编译前就知道操作的 Class。
Class clz = String.class;
- 对象名.getClass()。
String str = new String("Hello");
Class clz = str.getClass();
- 如果是基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。
除了上述几种种方法,还可以通过ClassLoader类的loadClass()方法来获取Class对象,这种方式常用于加载外部或动态生成的类。
Java反射API有几类?
反射 API 用来生成 JVM 中的类、接口或则对象的信息。
Class 类:反射的核心类,可以获取类的属性,方法等信息。
Field 类:Java.lang.reflect 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。
Method 类:Java.lang.reflect 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
Constructor 类:Java.lang.reflect 包中的类,表示类的构造方法。
反射使用的步骤?
获取想要操作的类的Class对象,这是反射的核心,通过Class对象我们可以任意调用类的方法。
调用 Class 类中的方法,既就是反射的使用阶段。
使用反射 API 来操作这些信息。
具体可以看下面的例子:
public class Student {private Integer age;public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public static void main(String[] args) {//正常调用Student student = new Student();student.setAge(16);System.out.println("Student Age : " + student.getAge());//使用反射调用try {Class<?> aClass = Class.forName("com.lzl.javaSE.test8.Student");Method setAge = aClass.getMethod("setAge", Integer.class);Constructor<?> studentConstructor = aClass.getConstructor();Object studentObject = studentConstructor.newInstance();setAge.invoke(studentObject, 18);Method getAge = aClass.getMethod("getAge");System.out.println("Student Age : " + getAge.invoke(studentObject));} catch (ClassNotFoundException | InstantiationException | InvocationTargetException | NoSuchMethodException |IllegalAccessException e) {throw new RuntimeException(e);}}
}
从代码中可以看到我们使用反射调用了 setAge方法,并传递了 16 的值。之后使用反射调用了 getAge 方法,输出其年龄。上面的代码整个的输出结果是:
Student Age : 16
Student Age : 18
从这个简单的例子可以看出,一般情况下我们使用反射获取一个对象的步骤:
- 获取类的 Class 对象实例
Class<?> aClass = Class.forName("com.lzl.javaSE.test8.Student");
- 根据 Class 对象实例获取 Constructor 对象
Constructor<?> studentConstructor = aClass.getConstructor();
- 使用 Constructor 对象的 newInstance 方法获取反射类对象
Object studentObject = studentConstructor.newInstance();
而如果要调用某一个方法,则需要经过下面的步骤:
- 获取方法的 Method 对象
Method setAge = aClass.getMethod("setAge", Integer.class);
- 利用 invoke 方法调用方法
setAge.invoke(studentObject, 18);
使用反射拿到私有属性值
Java通过反射机制可以获取和操作类、方法、字段等信息。在Java中,私有属性对外不可见,因此不能直接访问私有属性的值。但是,我们可以使用反射机制来绕过访问限制,获取私有属性的值。
下面是获取私有属性值的示例代码:
import java.lang.reflect.Field;public class PrivateFieldTest {private String privateField = "private value";public static void main(String[] args) throws Exception {PrivateFieldTest obj = new PrivateFieldTest();// 获取私有属性对象Field field = PrivateFieldTest.class.getDeclaredField("privateField");// 设置可访问私有属性field.setAccessible(true);// 获取私有属性值String value = (String) field.get(obj);// 输出私有属性值System.out.println("privateField value: " + value);}
}
在上面的示例代码中,我们首先定义了一个私有属性privateField,然后在main方法中通过反射机制获取privateField的值。这里要注意,我们要通过类的getDeclaredField方法获取私有属性对象,并且要将其设置为可访问状态。
另外,我们还需要调用Field类的get方法获取私有属性的值,其中第一个参数是对象实例,表示要获取该对象中的私有属性值。最后我们将获取到的私有属性值输出。
Java反射面试总结(一)相关推荐
- Java反射面试总结(二)
为什么引入反射概念?反射机制的应用有哪些? 我们来看一下 Oracle 官方文档中对反射的描述: 从 Oracle 官方文档中可以看出,反射主要应用在以下几方面: 反射让开发人员可以通过外部类的全路径 ...
- java 反射面试,Spring-MVC 必看笔记
前言 回顾这一年,我的付出终归是没有白费的!很快,今天是 2022年了,激烈的金三银四已经没有多少日子就有上场了!所以今天,我挑选了"美团+字节+腾讯"等三家的一二三面问题,在此篇 ...
- Java 虚拟机:Java 内存区域及对象,java 反射面试
1.计算机存储单位 从小到大依次为位 Bit.字节 Byte.千字节 KB.兆 M.千兆 GB.TB,相邻单位之间都是 1024 倍,1024 为 2 的 10 次方,即: 1Byte = 8bit ...
- 反射 字段_详解面试中常考的 Java 反射机制
反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法. 反射是一项高级 ...
- 深入理解Java反射+动态代理,java开发面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起在群里探讨技术. 答: ...
- 大白话说Java反射:入门、使用、原理,BAT 面试官 如何面试
写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...
- java 反射获取属性名和值_面试官这样问我Java反射原理,我刚好都会
上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...
- 【面试】Java 反射机制(常见面试题)
文章目录 前言 一.反射是什么? 二.为什么要有反射 三.反射 API 3.1 获取 Class 对象的三种方式 3.2 获取成员变量 3.3 获取构造方法 3.4.获取非构造方法 四.实践 五.常见 ...
- 【Java面试】Java反射
文章目录 什么是反射机制? 说一说你对Java反射机制的理解 Java反射在实际项目中有哪些应用场景? 什么是反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方 ...
最新文章
- order by总结
- 批处理解决“易语言难题”
- c语言e怎么表示_C语言程序设计(山东联盟)
- python中的format什么意思中文-python的format什么意思
- UVa 537 - Artificial Intelligence?
- Qt 【widget如何铺满窗口】
- 在东岸听刘元演奏萨克斯
- hdu 2049 考新郎
- maven分模块构建项目工程
- Flash: 涅磐与重生
- 【编程好习惯】使用sizeof减少内存操作失误
- Xcode9.0、Xcode9.1修改模拟器尺寸
- c# 判断网络是连接到互联网
- 第十章(项目沟通管理)知识点
- nfcwriter下载 ios_被苹果封杀至今的下载神器,更新适配iOS 13系统
- 一款多核架构GPU IP有多达33种配置!Imagination要守住移动市场攻向云端
- 目标检测:速度和准确性比较(Fater R-CNN,R-FCN,SSD,FPN,RetinaNet和YOLOv3)
- python访问陌生人qq空间_Python爬虫获取QQ空间信息(上)
- tiny4412 裸机程序 六、重定位代码到IRAM+0x8000
- 动态相关系数dcc_【分享吧】基于DCCMVGARCH模型的期货与股票市场收益率波动的动态相关分析...
热门文章
- Microsoft Office Project 2010 操作手册
- 网络云存储技术Windows server 2012 (项目十二 为企业构建虚拟共享服务(工作组模式下的DFS))
- 什么是ClassLoader
- outlook HTML签名制作方法
- linux 剪刀石头布c语言,C语言实现最简单的剪刀石头布小游戏示例
- TI AWR1843毫米波雷达采集三维点云数据(ROS)
- [驱动][转载] 使自己的驱动无法卸载(包括Xuetr)
- Android自适应屏幕大小和layout布局(转)
- for(auto ite:xxx)
- 任意文件下载、文件读取