文章目录

  • java 反射机制
    • 反射机制概念
      • java反射提供的功能
    • 反射的基本使用
      • 反射使用步骤(获取Class对象、调用对象方法)
    • 反射使用
      • 例子People
      • 获取Class的三种方法(获取一个类的字节码对象)
      • 获取一个类的所有信息
        • 获取类中的变量(Field)
        • 获取类中的方法(Method)
        • 获取类的构造器(Constructor)
        • 获取注解
      • 通过反射调用方法
    • 反射的应用场景
      • Spring的IOC容器
      • 反射+抽象工程模式
      • JDBC加载数据库驱动类
    • 反射的优缺点
      • 反射的优点:
      • 反射的缺点:
    • 反射小问答
      • 被反射的类是否一定需要无参构造方法?
    • 反射总结
    • 最后

java 反射机制

反射机制概念

  • 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。反射被视为动态语言的关键。简单来说反射就是java的各种成分映射成对应的java类。
  • 通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以。包括构造方法,属性,方法。

java反射提供的功能

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

java不是动态语言,但是通过反射机制实现动态机制。

反射的基本使用

java反射的主要组成

  • Class:任何运行在内存中的所有类都是该Class类的实例对象,每个Class类对象内存都包含了本来的所有信息。通过反射干任何事情,都要先去找Class

    • 类内部主要信息:

      • Field:所有属性
      • Constructor:所有构造方法
      • Method:所有方法
  • Field:描述一个类的属性,内部包含了该属性的所有信息,例如数据类型,属性名,访问修饰符
    • 类内部主要信息

      • 标注在属性上的注解
      • 属性名
      • 属性的数据类型(boolean/double/int/String …)
      • 属性访问修饰符(public/private/protected)
  • Constructor:描述一个类的构造方法,内部包含了构造方法的所有信息,例如参数类型、参数名称、访问修饰符
    • 类内部主要信息

      • 构造方法的访问修饰符
      • 构造方法的参数
        • 参数的数据类型
        • 参数的名称
        • 标注在参数上的注解
  • Method:描述一个类的所有方法(包括抽象方法),内部包含了该方法的所有信息,与Constructor类似,不同之处就是Method拥有返回值类型信息,因为构造方法是没有返回值的
    • 类内部主要信息

      • Constructor类内部主要信息
      • 方法返回值类型(Int/double0

反射使用步骤(获取Class对象、调用对象方法)

  • 获取想要操作的类的Class对象,它是反射的核心,通过Class对象我们可以任意调用类的方法
  • 调用Class类中的方法,即就是反射的使用阶段
  • 使用反射API来操作这些信息

反射使用

例子People

public class People {public String name;public int age;private double weight;public People(){}public People(String name,int age){this.name=name;this.age=age;}public void getInfo(){System.out.println(name+"的年龄是:"+age);}
}

获取Class的三种方法(获取一个类的字节码对象)

​ 当使用javac编译后,就会产生一个.class文件,当字节码文件被装载进虚拟机执行的时候,会在内存中生成Class对象,包含了该类内部的所有信息,在程序运行阶段可以获取这些信息。

  • 使用对象获取,使用对象的getClass获取

    People people = new People();
    Class clazz=people.getClass();
    
  • 使用静态属性class

    只有在编译前就已经声明了该类的类型才能获取到Class对象

    Class clazz =People.class;
    
  • 使用Class类的静态方法forName(通过类的全限定名获取该类的 Class 对象)

    • 类要写全名

      Class clazz = Class.forName("")
      
    • 通过类的全路径名获取Class对象会抛出一个异常,要用try——catch来捕获异常。

​ 当我们拿到class对象后就可以,获取类信息、调用其方法、获取其属性。

获取一个类的所有信息

​ Class对象中国包含了该类的所有信息,在编译期间我们能看到的信息及时该类的变量、方法、构造器,在运行时最常被获取的也是这些信息

每种功能内部以Declared细分为两类:

  • 有Declared修饰的方法:可以获取该类内部包含的所有变量、方法和构造器,但是无法获取继承下来的信息
  • 无Declared修饰的方法:可以获取该类中public修饰的变量、方法和构造器,以及获取继承下来的信息

如果要想获取类中所有的(包含继承)的变量、方法和构造器,则需要同时调用,并且用set集合存储他们获得的遍历,一方获取到相同的东西。

获取类中的变量(Field)
  • Field[] getField():获取类中所有被public修饰的所有变量
  • Field getField(String name):根据变量名获取类中的一个变量,改变了必须是被public修饰
  • Field[] getDeclaredFields):获取类中所有的变量,但无法获取继承下来的变量
  • Field getDeclaredField(String name):根据名称获取类中的变量,也无法获取继承下来的变量
获取类中的方法(Method)
  • Method[] getMethods():获取类中被public修饰的所有方法
  • Method getMethod(String name, Class…<?> paramTypes):根据名字和参数类型获取对应方法,该方法必须被public修饰
  • Method[] getDeclaredMethods():获取所有方法,但无法获取继承下来的方法
  • Method getDeclaredMethod(String name, Class…<?> paramTypes):根据名字和参数类型获取对应方法,无法获取继承下来的方法
获取类的构造器(Constructor)
  • Constuctor[] getConstructors():获取类中所有被public修饰的构造器
  • Constructor getConstructor(Class…<?> paramTypes):根据参数类型获取类中某个构造器,该构造器必须被public修饰
  • Constructor[] getDeclaredConstructors():获取类中所有构造器
  • Constructor getDeclaredConstructor(class…<?> paramTypes):根据参数类型获取对应的构造器

如果父类的属性用protected修饰,利用反射是无法获取到的

获取注解
  • Annotation[] getAnnotations():获取该对象上的所有注解
  • Annotation getAnnotation(Class annotaionClass):传入注解类型,获取该对象上的特定一个注解
  • Annotation[] getDeclaredAnnotations():获取该对象上的显式标注的所有注解,无法获取继承下来的注解
  • Annotation getDeclaredAnnotation(Class annotationClass):根据注解类型,获取该对象上的特定一个注解,无法获取继承下来的注解

​ 只有注解的@Retension标注为RUNTIME时,才能通过反射获取到该注解

​ 详情请点击:注解详情

通过反射调用方法

​ 通过反射获取到某个Method类对象后,可以通过调用invoke方法执行

  • invoke(Oject obj, Object... args):参数``1指定调用该方法的**对象**,参数2`是方法的参数列表值。
  • 如果调用的方法是静态方法,参数1只需要传入null,因为静态方法不与某个对象有关,只与某个类有关。

反射的应用场景

常见场景有三种:

  • Spring实例化对象:当程序启动时,Spring会读取配置文件applicationContext.xml并解析出里面所有的标签实例化到IOC容器中
  • 反射+工程模式:通过反射消除工厂中的多个分支,如果需要生产新的类,无序关注工厂类,工厂类可以应对各种新增类,反射可以使得程序更加健壮
  • JDBC连接数据库:使用JDBC连接数据库时,指定连接数据库的驱动类时用到反射加载启动类

Spring的IOC容器

​ 在Spring中,经常会用到一个上下文配置文件applicationContext.xml里面就是关于bean的配置,查询启动时会读取该xml文件,解析出所有的标签,并实例化对象放入IOC容器中,IOC容器本质上就是一个工厂,通过工厂传入标签的id属性获取对应的实例。

​ Spring在实例化对象的过程经过简化后,可以理解为反射实例化对象的步骤

  • 获取Class对象的构造器
  • 通过构造器调用newInstance()实例化对象

当然Spring在实例化对象时,做了非常多额外的操作,才能让现在的开发便捷且稳定

反射+抽象工程模式

​ 传统的工程模式,如果需要生产新的子类,就需要修改工厂类,在工厂类中增加新的分支。

​ 利用反射和工厂模式相结合,在生产新子类时,工厂类不需要修改任何东西,可以专注于子类的实现,当子类确定下来时,工厂也就可以生成该子类了、

反射+抽象工厂的核心思想是:

  • 在运行时通过参数传入不同子类的全限定名获取到不同的Class对象,调用newInstance()方法返回不同的子类。

JDBC加载数据库驱动类

​ 在导入第三方库时,JVM不会主动去加载外部导入的类,而是等到真正使用时,才会去加载需要的类,正因为如此,我们可以在获取数据库连接时传入驱动类的全限定名,交给JVM加载该类

反射的优缺点

反射的优点:

  • 增加程序灵活性:面对需求变更时,可以灵活地实例化不同的对象
  • 增加扩展性,降低耦合性,无序提前硬编码目标类。

反射的缺点:

  • 破坏类的封装性:可以强制访问private修饰的信息
  • 性能损耗:反射相比直接实例化对象、调用方法、访问变量、中间需要很多检查步骤以及解析步骤,JVM无法对其进行优化

反射小问答

被反射的类是否一定需要无参构造方法?

​ 不需要,因为有参数构造方法也可以反射。

反射总结

  • 反射的思想:反射就想一面镜子,只有在运行时才能看到自己是谁,可以获取到自己的信息,甚至实例化对象
  • 反射的作用:在运行时才确定实例化对象,使得程序更加的健壮,面对需求变更时,可以最大程度地做到不修改程序源码的情况下,应对不同的场景,实例化不同类型的对象。
  • 反射的应用场景:Spring的IOC容器;反射+工厂模式,使得工厂类更加稳定;JDBC连接数据库时加载驱动类
  • 反射的三个特点:增加程序的灵活性、破坏类的封装性以及性能损耗

最后

  • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
  • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
  • 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

月黑雁飞高,反射全知道——剖析java反射机制相关推荐

  1. java 反射 Gc_深入浅析Java反射机制

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

  2. 如何理解java反射_怎么理解java反射

    怎么理解java反射? 概述 Java 反射是可以让我们在运行时获取类的方法.属性.父类.接口等类的内部信息的机制.也就是说,反射本质上是一个"反着来"的过程.我们通过new创建一 ...

  3. 如何优化java反射,如何有效地使用Java反射

    反射是一种内置机制,用于在执行时对Java程序进行内省.它可以用来检查.修改和转换Java程序,而不会影响现有代码.这个强大的特性可以用来扩展程序的功能,在运行时检查类或对象的内部结构.本文试图探究其 ...

  4. java 防止反射_如何防止JAVA反射对单例类的攻击?

    在我的上篇随笔中,我们知道了创建单例类有以下几种方式: (1).饿汉式; (2).懒汉式(.加同步锁的懒汉式.加双重校验锁的懒汉式.防止指令重排优化的懒汉式); (3).登记式单例模式; (4).静态 ...

  5. java 反射 本类,关于Java反射中基本类型的class有关问题

    关于Java反射中基本类型的class问题 1. 基本类型的class和其对应包装类的class是不同的,所以在获得Method指定参数的时候,需要精确指定参数的类型,即 setInt(int x) ...

  6. java反射减少servlet_利用java 反射机制来实现一个servlet处理多种请求

    如果我们想在一个servlet中处理多种请求(比如新闻的添加.删除),简单的可以在jsp提交表单的action路径中添加一个键值对,然后再servlet中接收后根据不同的值来调用不同的方法. jsp端 ...

  7. 【反射的使用】java反射的复习

    反射 1.类加载器 1.1类加载 程序要使用一个类需要将类进行加载,连接,初始化 类加载:将class读入内存,创建一个class对象 类的连接:检查,协调 类的初始化:如果父类未初始化,会优先初始化 ...

  8. c 与java 反射性能_谈谈Java 反射的快慢

    [相关学习推荐:java基础教程] 反射到底是好是坏 说到Java 中的反射,初学者在刚刚接触到反射的各种高级特性时,往往表示十分兴奋,甚至会在一些不需要使用反射的场景中强行使用反射来「炫技」.而经验 ...

  9. 如何理解java反射_如何理解java反射?

    一.反射基本概念 反射之中包含了一个"反"的概念,所以要想解释反射就必须先从"正"开始解释,一般而言,当用户使用一个类的时候,应该先知道这个类,而后通过这个类产 ...

最新文章

  1. 一款可以在BCH链上养大熊猫的游戏——CryptoPandas
  2. 线程安全机制 python
  3. cnpm install -g live-server 安装服务
  4. 回顾 | 使用Visual Studio Code进行端到端应用程序开发
  5. 突破极限–如何将AeroGear Unified Push用于Java EE和Node.js
  6. android人脸识别demo_零门槛解决Windows人脸识别应用开发难题
  7. 打docker镜像_从安全到镜像流水线,Docker 最佳实践与反模式一览
  8. android应用程序的生命周期,Android应用程序的生命周期.doc
  9. Spring Boot 中文乱码问题解决方案汇总
  10. 基本地图加载完整示例
  11. 电子技术课程设计—交通灯控制系统设计
  12. 勒索病毒 -- “永恒之蓝”NSA 武器免疫工具
  13. 美股相关交易规则与业务知识
  14. Groovy的规则脚本引擎实战
  15. PLS-00103: Encountered the symbol “DECLARE“
  16. IDRAC 固件升级操:
  17. pythonfor循环功能手工皂_轻松领悟for循环,做一款Python版手账
  18. 端到端的图像压缩----《Channel-wise Autoregressive Entropy Models For Learned Image Compression》论文笔记
  19. 使用ffmpeg对视频进行画面裁剪
  20. 金山毒霸6 、金山网镖6 增强版 发布在即!!!

热门文章

  1. 在服务器里面修改油画,油画错误如何修改?
  2. 快速分析出德邦快递揽收后没有物流的单号
  3. Foreman部署裸机
  4. java基于SpringBoot+Vue+nodejs的演唱会话剧娱乐项目售票系统 element
  5. 解决Cannot find module ‘meteor/meteor’ ‘meteor/check’ ‘meteor/mongo’
  6. Shapefile文件读取-文件头
  7. 基于STM32L431单片机和NB-IOT技术的低功耗追踪器
  8. 【新技能get】如何通过地址查看附件企业基本信息?
  9. ABCDE-入栈,不可能的出栈次序
  10. [BZOJ 2085]POI2010 Hamsters