广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java基础之反射详解
  • 198
分享到

Java基础之反射详解

2024-04-02 19:04:59 198人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言一、一个需求引出反射二、反射入门三、反射原理图四、反射相关类五、反射调用优化前言 反射是我们框架的灵魂,反射也是我们框架的一个底层基石,没有反射也就没有框架,如果我们学好了反

前言

反射是我们框架的灵魂,反射也是我们框架的一个底层基石,没有反射也就没有框架,如果我们学好了反射,对我们阅读框架底层是有很大班助的——阿俊。有些文章上来就讲反射,就会很懵逼,不知道是干啥的,所以我们就引出一些问题来看看为什么需要反射

一、一个需求引出反射

看下面的问题
根据配置文件reflection.properties指定信息,创建People对象并调用方法hi


classullpath= com.reflection.People
method=hi

思考:使用现有技术,能做吗?
我们可以来试一试
我们根据要求创建出两个类和一个配置文件

在这里插入图片描述

People 类


public class People {
    private String name="zlj";
    public void hi(){
        System.out.println("hi"+name);
    }
}

classullpath= com.reflection.People
method=hi

在QuestionReflectionQuestion类中进行测试,我们学Java的时候可知,可以通过如下的方法创建People对象并调用方法hi


public class QuestionReflectionQuestion {
    public static void main(String[] args) {
            //传统方式
        People people = new People();
        people.hi();
    }
}

那我们如何通过配置文件reflection.properties指定信息,创建People对象并调用方法hi呢?

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

尝试1:Java中有一个Properties类,可以读写配置文件,我们可以用它进行尝试


public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException {
        //我们尝试做一下-》明白反射
        //Java中有一个Properties类,可以读写配置文件,我们可以用它进行尝试
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String method = properties.get("method").toString();//method:hi
        System.out.println("classullpath:"+classullpath);
        System.out.println("method:"+method);
        //那我们可以不可以直接使用new classullpath();来创建呢?这样显然不行的
    }
}

结论:尝试失败,我们就可以使用反射机制来解决上述:通过配置文件reflection.properties指定信息,创建People对象并调用方法hi,下一节进行代码演示

二、反射入门

解决第一节问题的代码演示

分四个步骤:

1.加载类,返回class类型对象:cls
2.通过cls得到你的加载类com.reflection.People的对象实例
3.通过cls得到你加载的类com.reflection.People的method=hi的方法对象(即:在反射中,可以把方法视为对象(即:万物皆对象))
4.通过method调用方法:即通过方法对象来实现调用方法


public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String methodName = properties.get("method").toString();//method:hi
        System.out.println("====使用反射机制解决=====");
        //1:加载类,返回class类型对象:cls
        Class cls = Class.forName(classullpath);
        //2:通过cls得到你的加载类com.reflection.People的对象实例
        Object o = cls.newInstance();
        System.out.println("o的运行类型="+o.getClass());//运行类型
        //3.通过cls得到你加载的类com.reflection.People的method=hi的方法对象
        //即:在反射中,可以把方法视为对象(即:万物皆对象)
        Method method = cls.getMethod(methodName);
        //4.通过method调用方法:即通过方法对象来实现调用方法
        method.invoke(o);//传统方法:对象.方法()    反射机制 方法.invoke(对象)
    }
}

====使用反射机制解决=====
o的运行类型=class com.reflection.People
hizlj

我们先知道一下反射实现方式的步骤即可,一些类的介绍,我们后续会进行介绍

如果Java没有反射机制,Java就不是一种动态语言,而且我们所说的spring mybatis 框架就都不存在了,反射机制是框架的灵魂,也是底层机制的基石

反射机制的牛逼之处就在于:可以通过外部文件配置,在不修改源码的情况下,来控制程序(这就是开闭原则)
比如,我们在People类中新增cry方法,我们就不需要在QuestionReflectionQuestion类中新增 people.cry();这个方法,只需要在配置文件中reflection.properties进行如下修改method=cry即可。


====使用反射机制解决=====
o的运行类型=class com.reflection.People
cryzlj

三、反射原理图

前面我们对反射进行了一个快速入门,接下来,我们来介绍一下它的原理

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

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

我们可以拿第一节的例子,画图来说明

在这里插入图片描述

四、反射相关类

接下来讲完反射机制原理,我们就来看一下反射机制可以做那些事情

1.在运行时判断任意一个对象所属的类

2.在运行时构造任意一个类的对象

3.在运行时得到任意一个类所具有的成员变量和方法

4.在运行时调用任意一个对象的成员变量和方法

5.生成动态代理

反射相关的主要类:

1.java.lang.Class:代表个类, Class对象表示某 个类加载后在堆中的对象

2.java.lang.reflect.Method:代表类的方法

3.java.lang.reflect.Field: 代表类的成员变量

4.java.lang.reflect.Constructor:代表类的构造方法

我们上面第二节介绍了Method演示,我们接下来进行Field和Constructor演示
People.java


public class People {
    public String name="zlj";
    public People(){
        this.name="zzg";
    }
    public People(String name){
        this.name=name;
    }
    public void hi(){
        System.out.println("hi"+name);
    }
    public void cry(){
        System.out.println("cry"+name);
    }
}

QuestionReflectionQuestion.java


public class QuestionReflectionQuestion {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\reflection.properties"));
        String classullpath = properties.get("classullpath").toString();//classullpath:com.reflection.People
        String methodName = properties.get("method").toString();//method:hi
        String fieldName = properties.get("field").toString();
        String constructorName = properties.get("constructor").toString();
        System.out.println("====使用反射机制解决=====");
        //1:加载类,返回class类型对象:cls
        Class cls = Class.forName(classullpath);
        //2:通过cls得到你的加载类com.reflection.People的对象实例
        Object o = cls.newInstance();
        System.out.println("o的运行类型="+o.getClass());//运行类型
        //3.通过cls得到你加载的类com.reflection.Field 的field=name的字段
        //即:在反射中,可以把方法视为对象(即:万物皆对象)
        //getField不可以得到私有属性
        Field field = cls.getField(fieldName);
        //4.通过field 调用方法:即通过方法对象来实现调用方法
        //因为对象赋了初始值;所以就是zzg,而不是zlj
        System.out.println(field.get(o));
        System.out.println("People类的字段name是否为zlj:"+field.equals("zlj"));
        //构造器的3,4和Field 一样
        Constructor constructors = cls.getConstructor();//()中可以指定构造器参数类型。默认返回无参构造器
        System.out.println(constructors);
        Constructor constructor = cls.getConstructor(String.class);//传入构造参数的类型对象
        System.out.println(constructor);
    }
}

reflection.properties


classullpath= com.reflection.People
method=cry
field=name
constructor=People

演示


====使用反射机制解决=====
o的运行类型=class com.reflection.People
People类的字段name是否为zlj:false
public com.reflection.People()
public com.reflection.People(java.lang.String)

五、反射调用优化

前面我们说了反射的原理和反射的作用,接下来我们就说一下它的优缺点

反射优点和缺点

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

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

基于缺点,我们可以进行反射调用优化。
我们先看一下传统方法调用和反射机制调用的耗时


public class ReflectionOptimize {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        ReflectionOptimize.m1();
        ReflectionOptimize.m2();
    }
    //传统方法调用hi
    public static void m1(){
        People people = new People();
        long start = System.currentTimeMillis();
        for (int i=0;i<900000;i++){
            people.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方法调用hi耗时:"+(end-start));
    }
    //反射机制调用hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.reflection.People");
        Object o = cls.newInstance();
       Method method = cls.getMethod("hi");
12       
        long start = System.currentTimeMillis();
        for (int i=0;i<900000;i++){
           method.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射机制调用hi耗时:"+(end-start));
    }
}

传统方法调用hi耗时:4
反射机制调用hi耗时:19

结论:使用反射机制调用方法耗时更长
我们可以进行如下优化

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

1.Method和Field、 Constructor对象都有setAccessible()方法

2.setAccessible作用是启动和禁用访问安全检查的开关

3.参数值为true表示 反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查

在这里插入图片描述

代码第12行加入method.setAccessible(true);//反射的对象在使用时取消访问检查,提高反射的效率
代码效果演示


传统方法调用hi耗时:3
反射机制调用hi耗时:16

到此这篇关于Java基础之反射详解的文章就介绍到这了,更多相关Java反射内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java基础之反射详解

本文链接: https://www.lsjlt.com/news/125718.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java基础之反射详解
    目录前言一、一个需求引出反射二、反射入门三、反射原理图四、反射相关类五、反射调用优化前言 反射是我们框架的灵魂,反射也是我们框架的一个底层基石,没有反射也就没有框架,如果我们学好了反...
    99+
    2022-11-12
  • Java基础篇之反射机制详解
    目录1、反射概述1.1什么是反射1.2、反射能干什么2、解剖类2.1反射构造方法2.1.1反射无参的构造函数2.1.2反射“一个参数”的构造函数2.1.3反射...
    99+
    2022-11-12
  • 【Java 基础篇】Java 反射详解
    文章目录 导言一、反射的概念二、反射的原理三、反射的使用示例四、反射的应用场景五、反射的注意事项总结 导言 Java反射是指在运行时动态地获取类的信息,并可以通过该信息来操作类或对象。...
    99+
    2023-09-14
    java python 开发语言
  • JavaSE基础之反射机制(反射Class)详解
    目录一:反射机制概述二:反射Class1. 获取Class的三种方式 2. 通过反射实例化(创建)对象3. 通过读配置属性文件实例化对象4. 只让静态代码块执行5. 获取类...
    99+
    2022-11-13
  • Java反射机制基础详解
    目录1、什么是Java反射机制?2、反射机制原理3、Class类介绍3.1、Class类基本介绍3.2、Class类对象的获取方法Class.forname()3.3、可以获取Cla...
    99+
    2022-11-12
  • Java基础篇之反射机制示例详解
    目录一、什么是反射:二、反射的原理:三、反射的优缺点:四、反射的用途:五、反射机制常用的类:六、反射的基本使用:1、获得Class:主要有三种方法:2、判断是否为某个类的示例:3、创...
    99+
    2022-11-12
  • Java基础学习之反射机制原理详解
    目录一、什么是反射二、反射的原理三、反射的优缺点四、反射的用途五、反射机制常用的类六、反射的基本使用一、什么是反射 (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细...
    99+
    2022-11-13
  • 深入解析Java反射之基础篇
    目录前言一、回顾:什么是反射?二、反射的主要用途三、反射的基本运用1、获得 Class 对象2、判断是否为某个类的实例3、创建实例4、获取方法5、获取构造器信息6、获取类的成员变量(...
    99+
    2022-11-12
  • Python基础学习之反射机制详解
    目录什么是反射应用场景基本小栗子贴近实际应用的小场景什么是反射 在Python中,反射是指通过一组内置的函数和语句,在运行时动态地访问、检查和修改对象的属性、方法和类信息的机制。Py...
    99+
    2023-03-22
    Python反射机制 Python反射
  • Java 基础详解(泛型、集合、IO、反射)
    计划把 Java 基础的有些部分再次看一遍,巩固一下,下面以及以后就会分享自己再次学习的一点笔记!不是有关标题的所有知识点,只是自己觉得模糊的一些知识点。1.对于泛型类而言,你若没有指明其类型,默认为Object;2.在继承泛型类以及接口的...
    99+
    2023-05-30
    java 泛型 集合
  • Java基础之反射怎么使用
    本篇内容介绍了“Java基础之反射怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!反射是框架设计的灵魂(使用的前提条件:必须先得到代表...
    99+
    2023-07-05
  • Kotlin 基础教程之反射
    Kotlin 基础教程之反射概述反射是语言与库中的一组功能, 可以在运行时刻获取程序本身的信息.在Kotlin中,不仅可以通过发射获取类的信息,同时可以获取函数和属性的信息。也就是说,在在运行时刻得到一个函数或属性的名称和数据类型) 可以通...
    99+
    2023-05-31
    kotlin 反射
  • Go语言基础反射示例详解
    目录概述语法一、基本操作二、修改目标对象三、动态调用方法总结示例 概述 在程序运行期对程序动态的进行访问和修改 reflect godoc: https://golang.org/p...
    99+
    2022-11-12
  • 新手了解java 反射基础知识
    目录一、反射概述二、常用api三、创建Class对象的四种方式总结一、反射概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection...
    99+
    2022-11-12
  • Java高级特性基础之反射五连问
    目录1.反射的作用2.反射的优缺点3.反射的应用场景4.说一下反射的相关类有哪些5.获取Class对象的六种方式1.反射的作用 它赋予了我们在运行时分析类以及执行类中方法的能力。通过...
    99+
    2023-01-11
    Java高级特性 反射 Java高级特性 Java反射
  • Java基础之Maven详解
    目录一、Maven环境的搭建1. 为什么要学习Maven?2. Maven项目架构管理工具3. 下载安装Maven4. 配置环境变量5. 阿里云...
    99+
    2022-11-12
  • Java基础之StringBuffer详解
    目录一、前言二、用法三、结果四、长度 容量五、IStringBuffer接口六、value和capacity一、前言 StringBuffer是可变长的字符串 1.append 追加...
    99+
    2022-11-12
  • Java基础之ClassLoader详解
    目录一、ClassLoader简介二、内置的CLassLoader的类型三、BootstrapClassLoader四、ExtClassLoader五、AppClassLoader六...
    99+
    2022-11-12
  • Java基础之FastJson详解
    目录一、fastJson将json格式字符串转化成List集合二、fastJson将json格式字符串转化成对象三、FastJson将对象或集合转化成json格式字符串四、FastJ...
    99+
    2022-11-12
  • Java基础之TreeMap详解
    目录一、写在前面二、定义三、成员变量四、内部类五、构造器六、成员方法一、写在前面 TreeMap的底层数据结构是红黑树,且TreeMap可以实现集合元素的排序。 所以TreeMap...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作