前言

在使用框架进行开发时,我们的开发速度大大提升。我们感叹于它的神奇之处,我们使用它的时候,也要知道其“灵魂”。正所谓,无反射,不框架,框架的灵魂就是反射。
另外,我们在eclipse或者IDEA中编辑Java代码时,它们是怎么知道我们的对象有哪些方法,输入一个点就能给提示呢?
带着问题我们来谈谈反射。

概念

反射:是将一个类的各个部分封装为其他对象,这就是反射机制。
看着上面文邹邹的话语,想必大家并没有理解啥是反射。下面我们来通过一个例子来进行讲解。

我们来看一下我们的Java代码在计算机中经历的几个阶段:
第一个阶段:源代码阶段
首先,我们定义一个猫的类,包含名字,年龄,无参和全参构造方法,和一个猫叫的方法。
Cat.java如下:

public class Cat {private String name;//猫的名字private int age;//猫的年龄public Cat() {//无参构造方法}public Cat(String name, int age) {//全参构造方法this.name = name;this.age = age;}public void meow(){//猫叫的方法System.out.println("喵喵喵~~~");}
}

写完这个代码之后,我们并不能运行它,我们需要执行一个操作:编译。
通过Java自带的编译器,使用 javac 这个命令,编译 Cat.java 文件,如果编写的代码没有问题,会在磁盘上生成一个字节码文件:Cat.class 文件。
这个字节码文件放的是什么呢?
它主要包含三个主要的内容:

当然不止这三个内容,还有类的名称等等等等。

这就是java代码在计算机中的第一个阶段:

这时我们的代码还在硬盘,并没有进入内存。

我们先不谈第二个阶段,我们先来谈谈第三个阶段,也就是我们通常new对象的阶段。
第三个阶段:运行时阶段

这就是我们的运行时阶段。
从字节码文件到new出类的对象这又是一个怎样的过程呢?我们需要把字节码文件加载到内存中才能使用,这就要介绍我们的第二个阶段了。
第二个阶段:Class类对象阶段
在Java中万物皆对象,有一个对象来描述字节码文件;这个对象是Class类对象;
需要把字节码中的成员变量,构造方法,成员方法都表示出来,又这些可能不止一个,所以这三种需要由一个数组来存储,所以主要由三个主要的部分组成:

Field[] fields;//成员变量数组
Constuctor[] constuctors;//构造方法数组
Method[] method;//成员方法数组

可以看到,我们把它们存储到对象中了,然后就能够知道有哪些成员变量,哪些方法了,这就解答了我们前面的如何提示问题。
然后通过类对象创建对应的Cat类等对象。
三个阶段

获取字节码Class对象的三种方式

第一种方式
如果我们的java代码在第一个阶段时,它还没有进入内存,我们需要将它加载到内存,需要使用
Class.forName(“全类名”);方式将其加载到内存,获取Class对象;
第二种方式
如果我们的java代码在第二个阶段时,它还没有创建对象,但是我们已经把它它加载到了内存,获取到了它的类名,我们可以使用 类名.class的方式获取Class对象;
第三种方式
如果我们的java代码在第三个阶段时,已经有了该类的对象,我们只需要用 对象.getClass() 的方式获取Class对象;
下面我们就来演示一下这三种方法的使用;
首先我们创建一个包com.demo.domain(命名随自己来定),存放我们的实体类对象,本文使用Cat.java进行演示;

package com.demo.domain;public class Cat {private String name;//猫的名字private int age;//猫的年龄public Cat() {//无参构造方法}public Cat(String name, int age) {//全参构造方法this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void meow(){//猫叫的方法System.out.println("喵喵喵~~~");}
}

再创建一个包com.demo.reflect用来演示这三种方式;Demo1.java如下:

package com.demo.reflect;import com.demo.domain.Cat;public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//第一种方式,Class.forName("全类名")Class cls1 = Class.forName("com.demo.domain.Cat");System.out.println(cls1);//输出class com.demo.domain.Cat//第一种方式,类名.classClass cls2 = Cat.class;//在使用Cat类之前需要进行导入System.out.println(cls2);//输出class com.demo.domain.Cat//第三种方式,已经具有对象,使用对象.getClassCat cat = new Cat();Class cls3 = cat.getClass();System.out.println(cls3);//输出class com.demo.domain.Cat}
}

注意:本文没写Class的泛型。
那获取到的三个对象是什么关系呢?我们用一段代码,验证它们的内存地址是否相等。

//比较三个对象
System.out.println(cls1 == cls2);//true
System.out.println(cls2 == cls3);//true

输出均为true,可见它们的内存地址是相同的。
所以,同一个字节码文件,在同一个程序运行的过程中,只会被加载一次,三种方式获取的Class对象都是同一个。

Class对象功能:

  • Class对象功能:

    • 获取功能:

      1. 获取成员变量们

        • Field[] getFields() :获取所有public修饰的成员变量

        • Field getField(String name) 获取指定名称的 public修饰的成员变量

        • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符

        • Field getDeclaredField(String name)

      2. 获取构造方法们

        • Constructor<?>[] getConstructors()

        • Constructor getConstructor(类<?>… parameterTypes)

        • Constructor getDeclaredConstructor(类<?>… parameterTypes)

        • Constructor<?>[] getDeclaredConstructors()

      3. 获取成员方法们:

        • Method[] getMethods()

        • Method getMethod(String name, 类<?>… parameterTypes)

        • Method[] getDeclaredMethods()

        • Method getDeclaredMethod(String name, 类<?>… parameterTypes)

      4. 获取全类名

        • String getName()
  • Field:成员变量

    • 操作:

      1. 设置值

        • void set(Object obj, Object value)
      2. 获取值

        • get(Object obj)
      3. 忽略访问权限修饰符的安全检查

        • setAccessible(true):暴力反射
  • Constructor:构造方法

    • 创建对象:

      • T newInstance(Object… initargs)

      • 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

  • Method:方法对象

    • 执行方法:

      • Object invoke(Object obj, Object… args)
    • 获取方法名称:

      • String getName:获取方法名

反射好处

反射有很多的优势:

  1. 我们可以在程序运行过程中,操作这些对象。
  2. 可以为我们的程序进行解耦,提高程序的可扩展性。

相信大家对反射有了一定的了解,感谢大家的阅读。

欢迎关注

扫下方二维码即可关注微信公众号:code随笔

谈谈Java中的反射机制相关推荐

  1. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  2. java代码安全检测机制_全面解析:java中的反射机制,内含代码验证解析

    什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功 ...

  3. formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化

    今天来聊聊java中的反射机制,工作以后发现很多东西动不动就要使用反射或者动态代理,如果不能很好的理解反射,那么对于动态代理等一些重要的设计模式就会有种不够通透的感觉. 所谓的反射,就是在运行状态中, ...

  4. java中的反射机制是什么

    给大家介绍一下java中的反射机制,java中反射机制更体现出了java的灵活性.多态.和类之间的耦合性. 1:反射是一种间接操作目标对象的机制,只要给定类的名字,就可以通过反设机制获取所有的类信息. ...

  5. Java中的反射机制详讲

    Java中的反射机制详讲 1.反射机制_介绍_Class对象获取 2.反射机制_动态操作_构造器_方法_属性 3.动态编译_DanamicCompile_反射调用main方法问题 好文推荐:排序.查找 ...

  6. 【反射机制】Java中的反射机制,使用反射机制创建对象、访问属性、方法、构造方法等

    这篇文章主要是整理了Java中的反射机制,包括:反射机制概念.反射机制访问构造方法.反射机制访问普通方法.反射机制访问属性,反射机制访问修饰符. 目录 一.反射机制概念 二.反射机制使用 (1)加载C ...

  7. JAVA基础--JAVA中的反射机制详解

    JAVA反射机制     JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能 ...

  8. 根据实例详解Java中的反射机制

    概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java ...

  9. 黑马程序员,黑马论坛 ------JAVA中的反射机制

    文章来源:黑马程序员,黑马论坛 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法 ...

最新文章

  1. java设计模式----装饰器模式
  2. 机器人大牛 Daniela Rus 领衔!MIT 新算法实现软体机器人「本体感知」
  3. 理解 Memory barrier(内存屏障)无锁环形队列
  4. 基于Windows Socket 的网络通信中的心跳机制原理
  5. idea 无法打开项目_Premiere出现quot;项目看来已经损坏,无法打开”的解决方法...
  6. linux tty core code,linux tty core 源码分析(7)
  7. android EditText 控件中加入图片(非背景图片)
  8. 单片机C语言稳压程序,51单片机的基于MC34063的5V稳压器的设计 -(原理图+程序)...
  9. 解决方案:Coin3D安装编译以及配合VS2019、QT的使用
  10. oracle 11.2.0.3.0 client下载,oracle64位客户端 Instant Client
  11. android textview全部属性,Android TextView属性大全
  12. StretchDIBits函数隐含的图像坐标系设置
  13. 在 .NET 6 项目中使用 Startup.cs
  14. 安全赋能区域数字化转型,普陀区副区长徐树杰带队调研上海控安
  15. Shiro logout 302重定向,shiro 302解决方案
  16. FPGA驱动千兆以太网PHY但电脑只显示百兆
  17. 【Niagara 04】Tridium N4使用——生成报警信息
  18. 烟台大学CSDN俱乐部参加2012移动开发者大会见闻
  19. 关于双网卡PVE:openwrt(LEDE) + win10直通核显+ DSM918+ 实现HDMI与声卡直通HTPC的解决方案!!
  20. 电路硬件设计——PCB布局和布线

热门文章

  1. 干货 :集成学习入门介绍
  2. CD刻录之Nero Burning ROM
  3. 气泡变金属泡 挖掘Windows 7隐藏绚丽屏保
  4. 2012年第三届蓝桥杯C/CPP省赛B组古堡算式
  5. ts16949 软件开发流程图_TS16949 标准流程之汽车零部件项目开发流程
  6. 中国三维激光扫描仪市场趋势报告、技术动态创新及市场预测
  7. 安装了微信支付的安全控件,检测不到,总提示安装-解决方案
  8. java cygwin 乱码_Cygwin中文乱码怎么办?Cygwin乱码解决办法
  9. 使用yolov5训练自动驾驶目标检测数据集BDD100K
  10. Grade下载网页地址