当前位置: 首页 > news >正文

非零基础自学Java (老师:韩顺平) 第23章 反射(reflection) 23.2 反射机制

非零基础自学Java (老师:韩顺平)

✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】

第23章 反射(reflection)

文章目录

      • 非零基础自学Java (老师:韩顺平)
      • 第23章 反射(reflection)
        • 23.2 反射机制
          • 23.2.1 Java Reflection
          • 23.2.2 Java 反射机制原理示意图
          • 23.2.3 Java 反射机制可以完成
          • 23.2.4 反射相关的主要类
          • 23.2.5 反射优点和缺点
          • 23.2.6 反射调用优化 - 关闭访问检查

23.2 反射机制

23.2.1 Java Reflection

反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息(比如成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射在设计模式和框架底层都会用到

加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以,形象的称之为:反射

在这里插入图片描述

p 对象 → 类型 Person类

Class对象 cls → 类型 Class 类

23.2.2 Java 反射机制原理示意图

在这里插入图片描述

23.2.3 Java 反射机制可以完成
  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时得到任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的成员变量和方法
  • 生成动态代理
23.2.4 反射相关的主要类
  • java.lang.Class:代表一个类,Class对象表示某个类加载后在堆中的对象
  • java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法
  • java.lang.reflect.Field:代表类的成员变量, Field对象表示某个类的成员变量
  • java.lang.reflect.Constructor:代表类的构造方法, Constructor对象表示构造器

这些类都在 java.lang.reflection

【举个栗子】

package com.dingjiaxiong.reflection;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * ClassName: Reflection01
 * date: 2022/9/8 13:08
 *
 * @author DingJiaxiong
 */

public class Reflection01 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        //使用Properties 类可以读写 配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("E:\\re.properties"));

        String classfullPath = properties.get("classfullpath").toString();
        String methodName = properties.get("method").toString();

        //使用反射机制
        //加载类,返回Class 类型的对象 cls
        Class cls = Class.forName(classfullPath);
        //通过cls 得到加载类的对象实例
        Object o = cls.newInstance();

        System.out.println("o 的运行类型 = " + o.getClass());

        //得到方法
        //在反射中,可以把方法视为对象
        Method method1 = cls.getMethod(methodName);
        //调用方法
        method1.invoke(o);

        //java.lang.reflect.Field: 代表类的成员变量, Field 对象表示某个类的成员变量
        //得到name字段
        //getFiled 不能得到私有的属性
        Field nameField = cls.getField("age");
        System.out.println(nameField.get(o)); //反射:成员变量对象.get(对象)

        //java.lang.reflect.Constructor: 代表类的构造方法, Constructor 对象表示构造器
        Constructor constructor = cls.getConstructor();
        System.out.println(constructor);

        Constructor constructor2 = cls.getConstructor(String.class);
        System.out.println(constructor2);
    }
}

运行结果

在这里插入图片描述

23.2.5 反射优点和缺点

优点:

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

缺点:

  • 使用反射基本是解释执行,对执行速度有影响.

【举个栗子】

package com.dingjiaxiong.reflection;

import com.dingjiaxiong.Cat;

import javax.swing.text.html.CSS;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * ClassName: Reflection02
 * date: 2022/9/8 13:16
 *
 * @author DingJiaxiong
 */

public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {

        m1(); //传统
        m2(); //反射
        m3(); //反射优化
    }

    //传统方法调用hi
    public static void m1(){
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; 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.dingjiaxiong.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            hi.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.dingjiaxiong.Cat");
        Object o = cls.newInstance();
        Method hi = cls.getMethod("hi");
        
        hi.setAccessible(true); //在反射调用方法时,取消访问检查
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            hi.invoke(o); //反射调用方法
        }

        long end = System.currentTimeMillis();
        System.out.println("m3() 耗时 = " + (end - start));
    }
}

运行结果

在这里插入图片描述

23.2.6 反射调用优化 - 关闭访问检查
  • Method和Field、Constructor对象都有setAccessible()方法
  • setAccessible作用是启动和禁用访问安全检查的开关
  • 参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查

在这里插入图片描述

相关文章:

  • (一)Java算法:二分查找
  • [前缀和]Tokitsukaze and Strange Inequality Codeforces1678C
  • Stl中map、set 容器(数据结构:AVL树、红黑树)--C++
  • Chapter20: Machine Learning for In Silico ADMET Prediction
  • Ubuntu下安装Miniconda
  • No1.搭建基本的密码模式请求token(授权服务端)
  • 代码随想录二叉树——从中序与后序遍历序列构造二叉树
  • 【2023泰凌微笔试题】~ 题目及参考答案
  • 采用Python中Tkinter模块的Treeview 组件显示xml文件
  • synchronized的实现原理与应用
  • 网上商城之支付
  • 一次搞懂Java如何调用Kotlin的高级特性
  • MyBatis各种SQL操作及执行添加功能获取自增的主键
  • 【学习笔记】模拟赛题解
  • node.js 使用教程-3.gulp-file-include 详细教程
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • Hibernate最全面试题
  • isset在php5.6-和php7.0+的一些差异
  • Java IO学习笔记一
  • October CMS - 快速入门 9 Images And Galleries
  • Spring声明式事务管理之一:五大属性分析
  • vue-cli3搭建项目
  • Vue小说阅读器(仿追书神器)
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 如何在招聘中考核.NET架构师
  • 组复制官方翻译九、Group Replication Technical Details
  • ​学习一下,什么是预包装食品?​
  • #Linux(make工具和makefile文件以及makefile语法)
  • #NOIP 2014#Day.2 T3 解方程
  • #每天一道面试题# 什么是MySQL的回表查询
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • %check_box% in rails :coditions={:has_many , :through}
  • (1)SpringCloud 整合Python
  • (11)MATLAB PCA+SVM 人脸识别
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (转)memcache、redis缓存
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net 怎么循环得到数组里的值_关于js数组
  • .net对接阿里云CSB服务
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • @ConfigurationProperties注解对数据的自动封装
  • @RequestBody与@ResponseBody的使用
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [2021 蓝帽杯] One Pointer PHP
  • [30期] 我的学习方法
  • [4.9福建四校联考]
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]
  • [C++从入门到精通] 14.虚函数、纯虚函数和虚析构(virtual)