java框架底层学习交流,java框架学习网站教程交流

首页 > 实用技巧 > 作者:YD1662023-11-21 08:28:32

1.反射是什么

java反射是框架的灵魂,大量框架底层都用到了反射机制,例如Spring....

Java反射是在运行状态时,可以构造任何一个类的对象,获取到任意一个对象所属的类信息,以及这个类的成员变量或者方法,可以调用任意一个对象的属性或者方法。可以理解为具备了动态加载对象以及对对象的基本信息进行剖析和使用的能力的一种机制。

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

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

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

java框架底层学习交流,java框架学习网站教程交流(1)

根据以上流程我们一个类的创建过程如下所示:

java框架底层学习交流,java框架学习网站教程交流(2)

Java 反射主要涉及两个类(接口) ClassMember,如果把这两个类搞清楚了,反射基本就 ok 了。

Class 可以说是反射能够实现的基础;注意这里说的 Class与 class 关键字不是同一种东西。class 关键字是在声明 java 类时使用的;而 Class 是 java JDK 提供的一个类,完整路径为 java.lang.Class,本质上与 Math, String 或者你自己定义各种类没什么区别,其官方文档定义解释如下:

java框架底层学习交流,java框架学习网站教程交流(3)

对于每一种类,Java 虚拟机都会初始化出一个 Class 类型的实例,每当我们编写并且编译一个新创建的类就会产生一个对应 Class 对象,并且这个 Class 对象会被保存在同名 .class 文件里。当我们 new 一个新对象或者引用静态成员变量时,Java 虚拟机(JVM)中的类加载器系统会将对应 Class 对象加载到 JVM 中,然后 JVM 再根据这个类型信息相关的Class 对象创建我们需要实例对象或者提供静态变量的引用值。

比如创建编译一个 Shapes 类,那么,JVM 就会创建一个 Person 对应 Class 类的 Class实例,该 Class 实例保存了 Person 类相关的类型信息,包括属性,方法,构造方法等等,通过这个 Class 实例可以在运行时访问 Person 对象的属性和方法等。另外通过 Class类还可以创建出一个新的 Person 对象。这就是反射能够实现的原因,可以说 Class 是反射操作的基础。

需要特别注意的是,每个 class(注意 class 是小写,代表普通类)类,无论创建多少个实例对象,在 JVM 中都对应同一个 Class 对象。

项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用

Github地址:github.com/plasticene/…

Gitee地址:gitee.com/plasticene3…

*Shepherd进阶笔记

交流探讨qun:Shepherd_126

2.反射的实现

1)获取Class对象的三种方式:

ini

复制代码

/** 获取Class对象的方式: 1.Class.forName("全类名"):将字节码文件加载进内存,返回Class对象 2.类名.class:通过类名的属性class获取 3.对象.getClass():getClass()方法在Object类中定义着。 */ //1.Class.forName("全类名") Class cls1 = Class.forName("com.shepherd.reflect.Person"); System.out.println(cls1); //2.类名.class Class cls2 = Person.class; System.out.println(cls2); //3.对象.getClass() Person p = new Person(); Class cls3 = p.getClass(); System.out.println(cls3); //==比较三个对象 System.out.println(cls1==cls2);//true System.out.println(cls1==cls3);//true Class c = Student.class; System.out.println(c); System.out.println(c==cls1);//false

说 Class 是反射能够实现的基础的另一个原因是:Java 反射包 java.lang.reflect 中的所有类都没有 public 构造方法,要想获得这些类实例,只能通过 Class 类获取。所以说如果想使用反射,必须得获得 Class 对象

2)Class类的相关方法:Class 实例可以在运行时访问 相应 对象的属性和方法,构造方法等等

ini

复制代码

Class c = Student.class; //获取public类型的属性,包括父类的 Field[]fields = c.getFields(); System.out.println(Arrays.asList(fields)); //只获取当前类所有属性 Field[]declaredFields = c.getDeclaredFields(); System.out.println(Arrays.asList(declaredFields)); //获取当前类的方法 Method[]methods = c.getMethods(); System.out.println(Arrays.asList(methods)); //获取当前类的构造对象 Constructor constructor = c.getConstructor(); Student stu = (Student) constructor.newInstance(); System.out.println(stu);

这里需要注意:xxx.getFields()方法默认情况下,会返回本类、父类、父接口的公有属性,而xxx.getDeclaredFields()返回本类的所有属性,包括私有的属性。同理,反射API中其他getXXX和getDeclaredXXX的用法类似。

3)对于 Member 接口可能会有人不清楚是干什么的,但如果提到实现它的三个实现类,估计用过反射的人都能知道。我们知道类成员主要包括构造函数,变量和方法,Java 中的操作基本都和这三者相关,而 Member 的这三个实现类就分别对应他们。

复制代码java.lang.reflect.Field :对应类变量 java.lang.reflect.Method :对应类方法 java.lang.reflect.Constructor :对应类构造函数

3.反射的缺点

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.