什么是反射?

Java的反射是指在程序运行时,对于任意一个类,都可以获取到这个类的所有属性和方法,并能够对其进行操作。通过反射机制,可以在程序运行时动态地创建对象、调用方法、获取属性值等。反射可以帮助我们更轻松地实现一些复杂的功能,但也会带来一些性能上的损失。

Java反射机制的基本步骤:

  1. 获取Class对象:通过反射可以动态地获取类对象,即Class对象。Class对象是Java运行时系统中的一个重要概念,每个类都有一个与之对应的Class对象,通过Class对象可以获取类的所有信息。

示例代码:

Class clazz = Class.forName("java.lang.String"); // 获取String类的Class对象
  1. 创建对象:通过Class对象可以实例化一个具体的对象。

示例代码:

Object obj = clazz.newInstance(); // 实例化一个String对象
  1. 访问属性:通过反射可以获取和设置对象的属性,包括公共的和私有的。

示例代码:

Field field = clazz.getField("value"); // 获取value属性
Object value = field.get(strObj); // 获取value属性的值
field.set(strObj, newValue); // 设置value属性的值为newValue
  1. 调用方法:通过反射可以调用对象的方法,包括公共的和私有的。

示例代码:

Method method = clazz.getMethod("substring", int.class, int.class); // 获取substring方法
Object result = method.invoke(strObj, startIndex, endIndex); // 调用substring方法,传递参数startIndex和endIndex
  1. 执行构造函数:通过反射可以调用对象的构造函数来实例化对象。

示例代码:

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中是一种高级的语言特性,它允许程序在运行时动态地获取类的信息、访问和操作类的属性和方法等。因此,它的应用场景非常广泛,以下是一些例子:

  1. 框架开发:许多框架(如Spring)利用反射获取类的信息和属性,来实现依赖注入、控制反转等功能。

  2. 动态代理:利用反射机制来动态生成代码,从而实现对某些对象的代理。

  3. 注解解析:通过反射来获取类、方法、字段等的注解信息。

  4. Java序列化:反射机制使得可以在编译时未知的情况下,将对象序列化为字节流,然后再通过反射将字节流转换成对象。

  5. 反编译工具:反编译工具利用反射实现对Java代码的分析和探测,可以查看方法、字段的信息以及代码的执行流程等。

总之,反射机制是Java语言中非常有用的一种特性,能够极大地提高程序的可扩展性、灵活性和可维护性。

反射机制的优缺点有哪些?

优点

  1. 动态性:能够运行时动态获取类的信息,访问和操作类的属性和方法,提高了灵活性;例如可与动态编译结合 Class.forName(‘com.mysql.jdbc.Driver.class’),加载MySQL的驱动类;
  2. 适应性:反射机制不依赖于具体的硬件、操作系统和JVM,可以应用于任何Java程序中;
  3. 灵活性:反射机制提供了更灵活的编程方式,可以在不知道具体的类名的情况下,创建对象、调用方法等。

缺点

  1. 性能问题:使用反射性能较低,需要解析字节码,将内存中的对象进行解析。其解决方案是:通过 setAccessible(true) 关闭JDK的安全检查来提升反射速度;
  2. 安全问题:反射机制可以访问和修改对象的私有属性和方法,有可能会破坏程序的安全性和稳定性,因此必须谨慎使用;
  3. 可读性问题:反射机制动态调用方法和属性,代码可读性较差,不容易维护和调试。

总之,优点就是动态获取类信息,操作类的属性和方法们这是核心,缺点无非就是性能、安全和可读性,一定不要死记硬背,要通过原理去理解。

如何获取反射中的Class对象?

  1. Class.forName(“类的路径”);当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。
Class clz = Class.forName("java.lang.String");
  1. 类名.class。这种方法只适合在编译前就知道操作的 Class。
Class clz = String.class;
  1. 对象名.getClass()。
String str = new String("Hello");
Class clz = str.getClass();
  1. 如果是基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。

除了上述几种种方法,还可以通过ClassLoader类的loadClass()方法来获取Class对象,这种方式常用于加载外部或动态生成的类。

Java反射API有几类?

反射 API 用来生成 JVM 中的类、接口或则对象的信息。

  1. Class 类:反射的核心类,可以获取类的属性,方法等信息。

  2. Field 类:Java.lang.reflect 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。

  3. Method 类:Java.lang.reflect 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。

  4. Constructor 类:Java.lang.reflect 包中的类,表示类的构造方法。

反射使用的步骤?

  1. 获取想要操作的类的Class对象,这是反射的核心,通过Class对象我们可以任意调用类的方法。

  2. 调用 Class 类中的方法,既就是反射的使用阶段。

  3. 使用反射 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反射面试总结(一)相关推荐

  1. Java反射面试总结(二)

    为什么引入反射概念?反射机制的应用有哪些? 我们来看一下 Oracle 官方文档中对反射的描述: 从 Oracle 官方文档中可以看出,反射主要应用在以下几方面: 反射让开发人员可以通过外部类的全路径 ...

  2. java 反射面试,Spring-MVC 必看笔记

    前言 回顾这一年,我的付出终归是没有白费的!很快,今天是 2022年了,激烈的金三银四已经没有多少日子就有上场了!所以今天,我挑选了"美团+字节+腾讯"等三家的一二三面问题,在此篇 ...

  3. Java 虚拟机:Java 内存区域及对象,java 反射面试

    1.计算机存储单位 从小到大依次为位 Bit.字节 Byte.千字节 KB.兆 M.千兆 GB.TB,相邻单位之间都是 1024 倍,1024 为 2 的 10 次方,即: 1Byte = 8bit ...

  4. 反射 字段_详解面试中常考的 Java 反射机制

    反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法. 反射是一项高级 ...

  5. 深入理解Java反射+动态代理,java开发面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起在群里探讨技术. 答: ...

  6. 大白话说Java反射:入门、使用、原理,BAT 面试官 如何面试

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 文章 ...

  7. java 反射获取属性名和值_面试官这样问我Java反射原理,我刚好都会

    上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...

  8. 【面试】Java 反射机制(常见面试题)

    文章目录 前言 一.反射是什么? 二.为什么要有反射 三.反射 API 3.1 获取 Class 对象的三种方式 3.2 获取成员变量 3.3 获取构造方法 3.4.获取非构造方法 四.实践 五.常见 ...

  9. 【Java面试】Java反射

    文章目录 什么是反射机制? 说一说你对Java反射机制的理解 Java反射在实际项目中有哪些应用场景? 什么是反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方 ...

最新文章

  1. order by总结
  2. 批处理解决“易语言难题”
  3. c语言e怎么表示_C语言程序设计(山东联盟)
  4. python中的format什么意思中文-python的format什么意思
  5. UVa 537 - Artificial Intelligence?
  6. Qt 【widget如何铺满窗口】
  7. 在东岸听刘元演奏萨克斯
  8. hdu 2049 考新郎
  9. maven分模块构建项目工程
  10. Flash: 涅磐与重生
  11. 【编程好习惯】使用sizeof减少内存操作失误
  12. Xcode9.0、Xcode9.1修改模拟器尺寸
  13. c# 判断网络是连接到互联网
  14. 第十章(项目沟通管理)知识点
  15. nfcwriter下载 ios_被苹果封杀至今的下载神器,更新适配iOS 13系统
  16. 一款多核架构GPU IP有多达33种配置!Imagination要守住移动市场攻向云端
  17. 目标检测:速度和准确性比较(Fater R-CNN,R-FCN,SSD,FPN,RetinaNet和YOLOv3)
  18. python访问陌生人qq空间_Python爬虫获取QQ空间信息(上)
  19. tiny4412 裸机程序 六、重定位代码到IRAM+0x8000
  20. 动态相关系数dcc_【分享吧】基于DCCMVGARCH模型的期货与股票市场收益率波动的动态相关分析...

热门文章

  1. Microsoft Office Project 2010 操作手册
  2. 网络云存储技术Windows server 2012 (项目十二 为企业构建虚拟共享服务(工作组模式下的DFS))
  3. 什么是ClassLoader
  4. outlook HTML签名制作方法
  5. linux 剪刀石头布c语言,C语言实现最简单的剪刀石头布小游戏示例
  6. TI AWR1843毫米波雷达采集三维点云数据(ROS)
  7. [驱动][转载] 使自己的驱动无法卸载(包括Xuetr)
  8. Android自适应屏幕大小和layout布局(转)
  9. for(auto ite:xxx)
  10. 任意文件下载、文件读取