反射 p1 反射机制

这篇具有很好参考价值的文章主要介绍了反射 p1 反射机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

反射机制

引出反射

反射 p1 反射机制

  • 这样的需求在学习框架时特别多,即通过外部文件配置,在不修改源码的情况下,来控制程序,也符合设计模式的OCP原则(开闭原则:不修改源码,扩展功能)。

  • 代码演示:文章来源地址https://www.toymoban.com/news/detail-591228.html

    re.properties文件:

    classfullpath=com.hspedu.Cat
    method=cry
    

    Cat类:

    package com.hspedu;
    
    /**
     * @author: 86199
     * @date: 2023/5/18 10:09
     * @description:
     */
    public class Cat {
        private Strinag name = "招财猫";
        public int age = 10;
        
        public Cat() {
        }
        
        public Cat(String name) {
            this.name = name;
        }
    
        public void hi(){
            System.out.println("hi" + name);
        }
        public void cry(){
            System.out.println(name + "喵喵叫");
        }
    }
    

    ReflectionQuestion:

    package com.hspedu.reflection.question;
    
    import com.hspedu.Cat;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /**
     * @author: 86199
     * @date: 2023/5/18 10:14
     * @description:
     */
    public class ReflectionQuestion {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            //普通方式
    //        Cat cat = new Cat();
    //        cat.hi();
    
            //IO流,使用Preperties类读写配置文件
            Properties properties = new Properties();
            properties.load(
                    new FileReader("src\\com\\hspedu\\re.properties"));
    
            String classfullpath = properties.get("classfullpath").toString();
            String methodName = properties.getProperty("method");
            System.out.println(classfullpath);
            System.out.println(methodName);
    
            //使用反射解决
            //(1)加载类,返回Class类型的对象 cls
            Class cls = Class.forName(classfullpath);
            //(2)通过cls 得到你的加载的类 com.hspedu.Cat 的对象实例
            Object o = cls.newInstance();
            System.out.println("o 的运行类型 = " + o.getClass());//运行类型
            //(3)通过 cls 得到你加载的类 com.hspedu.Cat 的 methodName"hi" 的方法对象
            //   即:在反射中,可以把方法视为对象(万物皆对象)
            Method method = cls.getMethod(methodName);
            //(4) 通过method调用方法:即通过方法对象类实现调用方法
            System.out.println("============================");
            method.invoke(o);
            //可以直接通过修改配置文件,而不是源码来改变调用的方法
        }
    }
    
    /*运行结果:
    com.hspedu.Cat
    cry
    o 的运行类型 = class com.hspedu.Cat
    ============================
    招财猫喵喵叫
    */
    

反射机制

  1. 反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到;
  2. 加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这对象得到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以形象的称之为:反射。
  3. 在启动时,包含main方法的类被加载。它会加载所有需要的类。这些被加载的类又要加载它们需要的类,以此类推。
  • 反射原理图

    反射 p1 反射机制

  • 弹幕摘要:

    • 加载的过程在方法区,加载结果(对象)在堆区,不知道对不对;
    • 类加载是将数据放入的内存的方法区中,然后在堆创建一个class对象,说白了就是堆中的class是用来封装方法区数据的类
  • 疑惑:

    • 那为什么需要这样一个Class对象呢?

      • Class类的对象的作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要。
      • 是这样的,当我们new一个新对象或者引用静态成员变量时,Java虚拟机(JVM)中的类加载器子系统会将对应Class对象加载到JVM中,然后JVM再根据这个类型信息相关的Class对象创建我们需要实例对象或者提供静态变量的引用值。也就是说,Class对象对于类的实例化具有非常重要的意义。没它就没法new新对象和引用静态成员变量。

      ————————————————
      版权声明:本文为CSDN博主「一只野生饭卡丘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://blog.csdn.net/Searchin_R/article/details/84591735

反射相关的主要类

  1. java.lang.Class:代表一个类,Class对象表示某个类加载后在堆中的对象;
  2. java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法;
  3. java.lang.reflect.Field:代表类的成员变量,Field对象表示某个类的成员变量;
  4. java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器;
  • 代码演示

    package com.hspedu.reflection;
    
    import java.io.FileReader;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /**
     * @author: 86199
     * @date: 2023/5/20 10:52
     * @description:
     */
    public class Reflection01 {
        public static void main(String[] args) throws Exception{
            //1. IO流,使用Preperties类读写配置文件
            Properties properties = new Properties();
            properties.load(
                    new FileReader("src\\com\\hspedu\\re.properties"));
    
            String classfullpath = properties.get("classfullpath").toString();
            String methodName = properties.getProperty("method");
    
    
            //2. 使用反射解决
            //(1)加载类,返回Class类型的对象 cls
            Class cls = Class.forName(classfullpath);
            //(2)通过cls 得到你的加载的类 com.hspedu.Cat 的对象实例
            Object o = cls.newInstance();
            System.out.println("o 的运行类型 = " + o.getClass());//运行类型
            //(3)通过 cls 得到你加载的类 com.hspedu.Cat 的 methodName"hi" 的方法对象
            //   即:在反射中,可以把方法视为对象(万物皆对象)
            Method method = cls.getMethod(methodName);
            //(4) 通过method调用方法:即通过方法对象类实现调用方法
            System.out.println("============================");
            method.invoke(o);
    
            //java.lang.reflect.Field:代表类的成员变量,Filed对象白哦是某个类的成员变量
            //得到age字段
            //getField不能得到私有属性
            Field ageFiled = cls.getField("age");
            System.out.println(ageFiled.get(o));
    
            //java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器
            Constructor constructor = cls.getConstructor();//()中可以指定构造器参数类型,不指定返回无参构造器
            System.out.println(constructor);//Cat()
    
            Constructor constructor1 = cls.getConstructor(String.class);//传入String类的Class对象
            System.out.println(constructor1);//Cat(java.lang.String)
        }
    }
    
  • 反射的优缺点:

    • 优点:可以动态的创建和使用对象(也是框架的底层核心),使用灵活,没有反射机制,框架技术就失去了底层支撑。

    • 缺点:使用反射基本是解释执行,对执行速度有影响。

反射调用优化——关闭访问检查

  1. Method和Field、Constructor对象都有setAccessible()方法;
  2. setAccessible()作用是启动和禁用访问安全检查的开关;
  3. 参数值为true表示反射的对象在使用时取消访问检查,可以提高反射的效率。参数值为false则表示反射的对象执行访问检查。

反射 p1 反射机制

  • 代码演示:

    package com.hspedu.reflection;
    
    import com.hspedu.Cat;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @author: 86199
     * @date: 2023/5/20 11:20
     * @description: 测试反射调用的性能,和优化方案
     */
    public class Reflection02 {
        public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
            m1();
            m2();
            m3();
        }
    
        //这里先把hi()方法中的打印注释了
        //传统方法调用方法hi
        public static void m1(){
            Cat cat = new Cat();
            long start = System.currentTimeMillis();
            for (int i = 0; i < 90000000; i++){
                cat.hi();
            }
            long end = System.currentTimeMillis();
            System.out.println("m1() 耗时 = " + (end - start));
        }
    
        //反射机制调用方法hi
        public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class cls = Class.forName("com.hspedu.Cat");
            Object o = cls.newInstance();
            Method method = cls.getMethod("hi");
            long start = System.currentTimeMillis();
            for (int i = 0; i < 90000000; i++){
                method.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("m2() 耗时 = " + (end - start));
        }
    
        //反射优化:关闭访问检测
        public static void m3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class cls = Class.forName("com.hspedu.Cat");
            Object o = cls.newInstance();
            Method method = cls.getMethod("hi");
            method.setAccessible(true);//取消在访问调用方法时的访问检查
            long start = System.currentTimeMillis();
            for (int i = 0; i < 90000000; i++){
                method.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("m3() 耗时 = " + (end - start));
        }
    }
    /*运行结果
    m1() 耗时 = 3
    m2() 耗时 = 197
    m3() 耗时 = 168
    */
    

到了这里,关于反射 p1 反射机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring】手动实现Spring底层机制-问题的引出

    🎄欢迎来到@边境矢梦°的csdn博文🎄 🎄本文主要梳理手动实现Spring底层机制-问题的引出 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑

    2024年02月09日
    浏览(34)
  • Java笔记040-反射/反射机制、Class类

    目录 反射(reflection) 一个需求引出反射 反射机制 Java反射机制原理图 Java反射机制可以完成 反射相关的主要类 反射机制的优点和缺点 反射调用优化-关闭访问检查 Class类 基本介绍 代码解释部分 类加载方法 应用实例:Class02.java 获取Class类对象 代码解释部分 哪些类型有Class对象

    2024年02月09日
    浏览(37)
  • C# 子类强制转换为父类异常,引出的C#Dll加载机制,以及同类名同命名空间同dll程序集在C#中是否为同一个类的研究。

    已知,子类B继承自父类A,但是在代码运行时,B类强制转换为A类,却报代码转换异常。 很奇怪的问题吧,不过这个也是难得机会,去研究C#运行的底层原理。 下面是报错的代码片段。 下面是报错结果(其中的敏感字符串被替换成了xxx): 通过上面的代码可以看出,从子类中

    2024年02月13日
    浏览(31)
  • 什么是反射机制

    1.什么是类对象: 所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。 比方有一个Hero类:类对象就是用于描述这种类,都有什么属性,什么方法的。 获取类对象有3种方式 Class.forName Hero.class new Hero().get

    2024年02月05日
    浏览(29)
  • Java反射机制深入详解

    一.概念 反射就是把Java的各种成分映射成相应的Java类。 Class类的构造方法是private,由JVM创建。 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示

    2024年02月06日
    浏览(32)
  • Java反射机制是什么?

    Java 反射机制 是 Java 语言的一个重要特性。 在学习 Java 反射机制前,大家应该先了解两个概念,编译期和运行期。 编译期 是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把

    2024年02月12日
    浏览(31)
  • C#的反射机制

    当谈到C#的反射机制时,它提供了一种 动态 地在运行时获取和操作类型信息的能力。通过反射,可以 在编译时未知的情况下 ,使用类型信息来创建对象、调用方法、访问属性和字段等。下面是一些反射机制的重要概念和用法: Type 类型:Type 类型表示在代码中定义的类型(

    2024年02月10日
    浏览(40)
  • C# 反射机制详解

    Reflection,中文翻译为反射。 这是.Net中获取运行时类型信息的方式。 官方定义: 审查元数据并收集关于它的类型信息的能力。 元数据(编译以后的最基本数据单元) 就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义

    2024年02月07日
    浏览(28)
  • Java的反射机制

    Java 的反射机制允许在程序运行期间,借助反射 API 获取类的内部信息,并能直接操作对象的内部属性及方法。 Java 反射机制提供的功能: 在运行时,使用反射分析类的能力,获取有关类的一切信息(类所在的包、类实现的接口、标注的注解、类的数据域、类的构造器、类的

    2024年02月02日
    浏览(32)
  • Java反射、代理机制

    官方解释:反射允许对封装类的字段、方法和构造方法的信息进行编程访问。 虚拟机加载类文件后,会在方法区生成一个类对象,包含了类的结构信息,如字段、方法、构造方法等。反射是一种能够在程序运行时动态访问、修改类对象中任意属性的机制(包括private属性)。

    2024年02月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包