直通大厂必考题系列:深入详解Java反射机制与底层实现原理

createh51周前 (12-20)技术教程14

Java面试的时候经常会被问到Java反射机制,尤其喜欢问:

  1. Java反射机制?
  2. 为什么要用反射机制?
  3. Java反射机制的原理?
  4. Java反射机制用在什么地方等等?

今天主要分享以上内容,详解Java反射机制的底层实现@mikechen


Java反射机制是什么?

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

对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

用一句话总结就是反射可以实现在运行时可以知道任意一个类的属性和方法。


为什么要用反射?

Java Reflection功能非常强大,并且非常有用,比如:

  • 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等;
  • 获取任意对象的属性,并且能改变对象的属性;
  • 调用任意对象的方法;
  • 判断任意一个对象所属的类;
  • 实例化任意一个类的对象;
  • 通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等。


Java反射机制原理

Java反射操作的是java.lang.Class对象,所以要理解Java反射机制,就需要搞懂Class对象。

比如举一个简单的例子,创建一个对象:

MikeChen mikechen= new MikeChen();

在运行上面语句的时候,首先 JVM 启动,代码会编译成一个 .class 文件,然后被类加载器ClassLoader加载进 JVM 的内存中,并为之创建一个 java.lang.Class 对象。

我们的 MikeChen类会加载到方法区中,创建了的 MikeChen类的 Class 对象会到堆中。

理解 Java 的反射机制就是要理解 Class 类。

每个类的运行时的类型信息,用 Class 对象表示,又或者称之为字节码对象。

Class 文件的整体结构如下图所示:

它包含了与类相关的信息,而实例对象就是通过 Class 对象来创建的。

获取 Class 对象的方式:

  1. 实例对象调用 Object 类的getClass()方法;
  2. 通过属性类名.class直接获取;
  3. 调用 Class 类的forName()方法;
  4. 使用类加载器 ClassLoader 的getSystemClassLoader().loadClass()方法。
package com.mikechen.reflection;
 
import com.mikechen.model.Person;
 
public class ReflectionTest {
    public static void main(String[] args) throws Exception {
        //1. 实例对象.getClass()
        Person person = new Person();
        Class clz1 = person.getClass();
        System.out.println(clz1);
 
        //2,类名.class属性
        System.out.println(Person.class);
 
        //3. Class.forName()
        Class clz2 = Class.forName("com.mikechen.reflection.Person");
        System.out.println(clz2);
    }
}

以上三种方式都能获取 Person 类的字节码对象,但同时也存在区别:

  • 方法1:需要创建一个实例对象才能获取类的信息;
  • 方法2:则需要导入包否则无法通过编译;
  • 方法3:只需传入类名的字符串,这个类名是类完整路径;

我们一般平时是通过new的形式创建对象实际上就是通过这些Class来创建的,只不过这个class文件是编译的时候就生成的,程序相当于写死了给jvm去跑。

反射是什么呢?当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到,所以不用加载到jvm,而是在运行时根据需要才加载。


Java反射的应用场景

面向开发,反射应用最广泛的是中间件和框架,比如:

  • JDBC的Class.forName(driverClass)加载驱动;
  • Spring MVC 通过反射调用 controller 的方法,动态代理处理请求;
  • Spring IOC 容器,在创建 Bean 实例时和依赖注入时的反射。
  • RMI 反序列化,反射调用远程方法;
  • RPC Dubbo动态代理利用;

阿里架构师进阶从0到1全部合集(建议收藏)

相关文章

一文带你掌握Java框架的底层灵魂:反射 ,框架源码再也不头大了

1.反射是什么Java反射是框架的灵魂,大量框架底层都用到了反射机制,例如Spring....Java反射是在运行状态时,可以构造任何一个类的对象,获取到任意一个对象所属的类信息,以及这个类的成员变量...

Volatile的实现原理(看这篇就够了)

谈到并发编程就不得不提到并发三要素:原子性、可见性、有序性,而Volatile就会涉及到可见性与有序性,可见Volatile在并发编程的重要的地位。所以需要重点掌握Volatile,为了助大家掌握好V...

一文带你了解 Redis 的发布与订阅的底层原理

01、前言发布订阅系统在我们日常的工作中经常会使用到,这种场景大部分情况我们都是使用消息队列的,常用的消息队列有 Kafka,RocketMQ,RabbitMQ,每一种消息队列都有其特性,关于 Kaf...

阿里架构师整理一份企业级SSM架构实战文档,让你熟悉底层原理

前言通常我们按规模把软件分为小型软件、中型软件和大型软件,而大型软件的应用客户都是大型企业或商业组织等,所以业内习惯将大型软件称为企业级应用。传统的企业级应用开发提供的是信息化解决方案和应用软件,需要...

周末肝了一套高并发Netty开源框架,真香

JDK从1.4版本引入 NIO 的类库,但是其设计有点反人类,使用较为麻烦,需要熟练掌握Selector、 ServerSocketChannel、 SocketChannel、 ByteBuffer...

【文19】Java程序员需要具备哪些底层基础知识?

作为开发人员,可谓十八般武艺样样都需要,而在实际操作过程中,仍然不断的发现书到用时方恨少,必须不断的学习提升。底层的很多知识在大学期间都是必修课,可能不会直接用到,但在学习和开发中,可以帮助我们对知识...