第17章:随堂复习与企业真题(反射机制)

第17章:随堂复习与企业真题(反射机制)


一、随堂复习

1. 反射的概述(熟悉)

  • Java给我们提供了一套API,使用这套API我们可以在运行时动态的获取指定对象所属的类,创建运行时类的对象,调用指定的结构(属性、方法)等。
  • API:
    • java.lang.Class:代表一个类
    • java.lang.reflect.Method:代表类的方法
    • java.lang.reflect.Field:代表类的成员变量
    • java.lang.reflect.Constructor:代表类的构造器
    • … …
  • 反射的优点和缺点
    • 优点:
      • 提高了Java程序的灵活性和扩展性,降低了耦合性,提高自适应能力

      • 允许程序创建和控制任何类的对象,无需提前硬编码目标类

    • 缺点:
      • 反射的性能较低
        • 反射机制主要应用在对灵活性和扩展性要求很高的系统框架上
      • 反射会模糊程序内部逻辑,可读性较差
  • 反射,平时开发中,我们使用并不多。主要是在框架的底层使用。

2. Class:反射的源头

  • Class的理解 (掌握)

    针对于编写好的.java源文件进行编译(使用javac.exe),会生成一个或多个.class字节码文件。接着,我们使用
    java.exe命令对指定的.class文件进行解释运行。这个解释运行的过程中,我们需要将.class字节码文件加载(使用类的加载器)到内存中(存放在方法区)。加载到内存中的.class文件对应的结构即为Class的一个实例。
    
  • 获取Class的实例的几种方式(前三种)

    • 类.class
    • 对象.getClass()
    • (使用较多)Class调用静态方法forName(String className)
    • (了解)使用ClassLoader的方法loadClass(String className)
  • Class 可以指向哪些结构。

    简言之,所有Java类型!
    (1)class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
    (2)interface:接口
    (3)[]:数组
    (4)enum:枚举
    (5)annotation:注解@interface
    (6)primitive type:基本数据类型
    (7)void
    

3. 类的加载过程、类的加载器(理解)

  • 类的加载过程

    过程1:类的装载(loading)
    将类的class文件读入内存,并为之创建一个java.lang.Class对象。此过程由类加载器完成
    
    过程2:链接(linking)
    > 验证(Verify):确保加载的类信息符合JVM规范,例如:以cafebabe开头,没有安全方面的问题。
    > 准备(Prepare):正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。
    > 解析(Resolve):虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
    
    过程3:初始化(initialization)
    执行类构造器<clinit>()方法的过程。
    类构造器<clinit>()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。
    
  • 类的加载器

    5.1 作用:负责类的加载,并对应于一个Class的实例。
    
    5.2 分类(分为两种):
    > BootstrapClassLoader:引导类加载器、启动类加载器
         > 使用C/C++语言编写的,不能通过Java代码获取其实例
         > 负责加载Java的核心库(JAVA_HOME/jre/lib/rt.jar或sun.boot.class.path路径下的内容)
    
    > 继承于ClassLoader的类加载器
        > ExtensionClassLoader:扩展类加载器
                > 负责加载从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录下加载类库
        > SystemClassLoader/ApplicationClassLoader:系统类加载器、应用程序类加载器
                > 我们自定义的类,默认使用的类的加载器。
        > 用户自定义类的加载器
                > 实现应用的隔离(同一个类在一个应用程序中可以加载多份);数据的加密。
    

4. 反射的应用1:创建运行时类的对象(重点)

Class clazz = Person.class;

//创建Person类的实例
Person per = (Person) clazz.newInstance();

System.out.println(per);
要想创建对象成功,需要满足:
条件1:要求运行时类中必须提供一个空参的构造器
条件2:要求提供的空参的构造器的权限要足够。

5. 反射的应用2:获取运行时类所有的结构

(了解)获取运行时类的内部结构1:所有属性、所有方法、所有构造器
(熟悉)获取运行时类的内部结构2:父类、接口们、包、带泛型的父类、父类的泛型等

6. 反射的应用3:调用指定的结构(重点)

3.1 调用指定的属性(步骤)
步骤1.通过Class实例调用getDeclaredField(String fieldName),获取运行时类指定名的属性
步骤2. setAccessible(true):确保此属性是可以访问的
步骤3. 通过Filed类的实例调用get(Object obj) (获取的操作)
                  或 set(Object obj,Object value) (设置的操作)进行操作。

3.2 调用指定的方法(步骤)
步骤1.通过Class的实例调用getDeclaredMethod(String methodName,Class ... args),获取指定的方法
步骤2. setAccessible(true):确保此方法是可访问的
步骤3.通过Method实例调用invoke(Object obj,Object ... objs),即为对Method对应的方法的调用。
     invoke()的返回值即为Method对应的方法的返回值
     特别的:如果Method对应的方法的返回值类型为void,则invoke()返回值为null

3.3 调用指定的构造器(步骤)
步骤1.通过Class的实例调用getDeclaredConstructor(Class ... args),获取指定参数类型的构造器
步骤2.setAccessible(true):确保此构造器是可以访问的
步骤3.通过Constructor实例调用newInstance(Object ... objs),返回一个运行时类的实例。

7. 反射的应用4:注解的使用(了解)

8. 体会:反射的动态性

public class ReflectTest {

    //体会:静态性
    public Person getInstance(){
        return new Person();
    }

    //体会:反射的动态性
    //举例1:
    public <T> T getInstance(String className) throws Exception {

        Class clazz = Class.forName(className);

        Constructor con = clazz.getDeclaredConstructor();
        con.setAccessible(true);

        return (T) con.newInstance();

    }

    @Test
    public void test1() throws Exception {
        Person p1 = getInstance();
        System.out.println(p1);

        String className = "com.atguigu04.other.dynamic.Person";
        Person per1 = getInstance(className);
        System.out.println(per1);

        String className1 = "java.util.Date";
        Date date1 = getInstance(className1);
        System.out.println(date1);
    }

    //体会:反射的动态性
    //举例2:
    public Object invoke(String className,String methodName) throws Exception {
        //1. 创建全类名对应的运行时类的对象
        Class clazz = Class.forName(className);

        Constructor con = clazz.getDeclaredConstructor();
        con.setAccessible(true);

        Object obj = con.newInstance();

        //2. 获取运行时类中指定的方法,并调用
        Method method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true);
        return method.invoke(obj);
    }

    @Test
    public void test2() throws Exception {
        String className = "com.atguigu04.other.dynamic.Person";
        String methodName = "show";

        Object returnValue = invoke(className,methodName);
        System.out.println(returnValue);
    }

}

二、企业真题

2.1 反射概述

1. 对反射了解吗?反射有什么好处?为什么需要反射?(微*银行)
类似问题:
> Java反射的作用是什么?(三*重工、上海*和网络)
> Java反射机制的作用有什么?(上海明*物联网)
> 反射的具体用途?(阿***芝*信用项目组)

2. 反射的使用场合和作用、及其优缺点(*软国际)
类似问题:
> 反射机制的优缺点(君*科技)
> Java反射你怎么用的?(吉*航空)

3. 实现Java反射的类有什么?(君*科技)
类似问题:
> Java反射 API 有几类?(北京*蓝)

问API。

4. 反射是怎么实现的?(上海立*网络)

从Class说起。

2.2 Class的理解

1. Class类的作用?生成Class对象的方法有哪些?(顺*)

反射的源头。 主要有三种。

2. Class.forName(“全路径”) 会调用哪些方法 ? 会调用构造方法吗?加载的类会放在哪?(上*银行外包)

Class.forName() 会执行执行类构造器()方法。

不会调用构造方法

加载的类放在方法区。

2.3 类的加载

1. 类加载流程(汇**通、同*顺、凡*科技)

2.4 创建对象

1. 说一下创建对象的几种方法?(华油***集团、*科软、凡*科技)
类似问题:
> 除了使用new创建对象之外,还可以用什么方法创建对象?(*云网络)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 如何找到对象实际类的?(*度)

对象.getClass();

Object obj = new Date();

obj.getClass();// 获取到的是Date。
3. Java反射创建对象效率高还是通过new创建对象的效率高?(三*重工)

new 的方式。

2.5 调用属性、方法

1. 如何利用反射机制来访问一个类的方法?(神州**软件)
调用指定的方法(步骤)
步骤1.通过Class的实例调用getDeclaredMethod(String methodName,Class ... args),获取指定的方法
步骤2. setAccessible(true):确保此方法是可访问的
步骤3.通过Method实例调用invoke(Object obj,Object ... objs),即为对Method对应的方法的调用。
     invoke()的返回值即为Method对应的方法的返回值
     特别的:如果Method对应的方法的返回值类型为void,则invoke()返回值为null
2. 说一下Java反射获取私有属性,如何改变值?(阿****麻信用项目组)
调用指定的属性(步骤)
步骤1.通过Class实例调用getDeclaredField(String fieldName),获取运行时类指定名的属性
步骤2. setAccessible(true):确保此属性是可以访问的
步骤3. 通过Filed类的实例调用get(Object obj) (获取的操作)
                       或 set(Object obj,Object value) (设置的操作)进行操作。
针对于核心源码的api,内部的私有的结构在jdk17中就不可以通过反射调用了。

ava反射获取私有属性,如何改变值?(阿****麻信用项目组)

调用指定的属性(步骤)
步骤1.通过Class实例调用getDeclaredField(String fieldName),获取运行时类指定名的属性
步骤2. setAccessible(true):确保此属性是可以访问的
步骤3. 通过Filed类的实例调用get(Object obj) (获取的操作)
                       或 set(Object obj,Object value) (设置的操作)进行操作。
针对于核心源码的api,内部的私有的结构在jdk17中就不可以通过反射调用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/230259.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web漏洞原理与防御策略,web漏洞怎么挖掘

目录 Web安全的重要性 ​编辑常见的Web漏洞类型及其原理&#xff1a; 1、跨站脚本攻击&#xff08;XSS&#xff09;: 2、SQL注入: 3、跨站请求伪造&#xff08;CSRF&#xff09;: 4、远程文件包含&#xff08;RFI&#xff09;和本地文件包含&#xff08;LFI&#xff09;:…

[笔记]ARMv7/ARMv8 交叉编译器下载

开发 Cortex-A7、Cortex-A72 或其他 ARM 架构 profile 芯片时&#xff0c;经常需要下载对应架构的交叉编译器&#xff0c;所以写这篇笔记&#xff0c;用于记录一下交叉编译器下载流程&#xff0c;免得搞忘。 编译环境&#xff1a;ubuntu 虚拟机 下载地址 我们可以从 ARM 官网…

使用MfgTool烧写前需准备的文件

一. 简介 本文我们就来学习&#xff0c;如何将我们编译的 uboot&#xff0c;zImage&#xff08;内核镜像&#xff09;&#xff0c;xxx.dtb设备树文件&#xff0c;还有制作的根文件系统&#xff0c;这四个文件烧写到开发板中&#xff0c;最后 开发板能正常启动。 本文这里使用…

数据可视化软件的兴起:背后的驱动力

在当今信息时代&#xff0c;数据变得比以往任何时候都更为重要。数据可视化软件的广泛应用成为了一种趋势。那么&#xff0c;为什么越来越多的人选择使用数据可视化软件呢&#xff1f;今天我就以自己的工作经验为基础&#xff0c;进行简单的分析。 数据可视化软件能将枯燥的数…

分布式系统CAP理论与BASE理论

CAP理论 Cap理论又被称作布鲁尔定理&#xff08;Brewers theorem&#xff09;&#xff0c;它指出对于一个分布式系统来说&#xff0c;不可能同时满足如下三点&#xff1a; 一致性&#xff08;Consistency&#xff09; 可用性&#xff08;Availability&#xff09; 分区容错性…

STM32单片机项目实例:基于TouchGFX的智能手表设计(3)嵌入式程序任务调度的设计

STM32单片机项目实例&#xff1a;基于TouchGFX的智能手表设计&#xff08;3&#xff09;嵌入式程序任务调度的设计 目录 一、嵌入式程序设计 1.1轮询 1.2 前后台&#xff08;中断轮询&#xff09; 1.3 事件驱动与消息 1.3.1 事件驱动的概念 1.4 定时器触发事件驱动型的任…

软件设计师——面向对象技术(一)

&#x1f4d1;前言 本文主要是【面向对象技术】——软件设计师—面向对象技术的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#…

《微信小程序开发从入门到实战》学习四十五

4.4 云函数 云函数是开发者提前定义好的、保存在云端并且将在云端运行的JS函数。 开发者先定义好云函数&#xff0c;再使用微信开发工具将云函数上传到云空间&#xff0c;在云开发控制台中可看到已经上传的云函数。 云函数运行在云端Node.js环境中。 小程序端通过wx.cloud.…

【Python】Numpy库近50个常用函数详解和示例,可作为工具手册使用

本文以yolo系列代码为基础&#xff0c;在其中查找用到的numpy函数&#xff0c;包含近50个函数&#xff0c;本文花费多天&#xff0c;三万多字&#xff0c;通过丰富的函数原理和示例对这些函数进行详解。以帮助大家理解和使用。 目录 np.array()运行示例 np.asarray()函数解析运…

【网络】简单聊一下 TIME_WAIT

问题背景 笔者在看自己服务状态数据的时候&#xff0c;会发现有很多 tcp 的连接&#xff0c;也会发现有很多处于不同状态下的 tcp 连接&#xff0c;TIME_WAIT 的连接数有83个&#xff0c;为了弄清楚这个 TIME_WAIT 是什么&#xff0c;整理了下面的笔记用于梳理概念 基础流程…

RPC基础

RPC基础知识 RPC 是什么? RPC&#xff08;Remote Procedure Call&#xff09; 即远程过程调用&#xff0c;通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。 为什么要 RPC &#xff1f; 因为&#xff0c;两个不同的服务器上的服务提供的方法不在一个内存空间&…

使用 Tailwind CSS 完成导航栏效果

使用 Tailwind CSS 完成导航栏效果 本文将向您介绍如何使用 Tailwind CSS 创建一个漂亮的导航栏。通过逐步演示和示例代码&#xff0c;您将学习如何使用 Tailwind CSS 的类来设计和定制导航栏的样式。 准备工作 在开始之前&#xff0c;请确保已经安装了 Tailwind CSS。如果没…

聚观早报 |华为畅享 70正式开售;梦饷科技双12玩法

【聚观365】12月8日消息 华为畅享 70正式开售 梦饷科技双12玩法 华为Mate X5应对火海挑战 谷歌发布AI模型Gemini 字节跳动开启新一轮回购 华为畅享 70正式开售 精致外观与创新科技兼具的华为畅享 70正式开售&#xff0c;1199元起搭载6000mAh超大电池&#xff0c;带来超强…

ModStartBlog v8.7.0 LayUI全新升级,文件顺序选择

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装 …

酿酒生产废水处理的设备需要哪些

酿酒生产废水处理的设备需要以下几种&#xff1a; 1. 格栅&#xff1a;用于去除废水中较大的漂浮物&#xff0c;如酒糟和塑料袋等。 2. 沉淀池或澄清器&#xff1a;进一步去除废水中更小的悬浮物和颗粒物&#xff0c;同时使有机物进行厌氧分解。 3. 过滤器和活性炭吸附装置&…

在阿里云国际上构建共享虚拟主机业务

我们需要3个ECS实例&#xff0c;1个RDS MySQL实例和2个域名。我将使用该域作为我的主域和辅助域。sarathy.infosarathy.site 以下架构图左侧所示的两个 ECS 实例将托管我们的主网站。一个ECS实例用于部署WHMCS&#xff0c;另一个实例用于部署WordPress。WordPress 和 WHMCS 都…

HarmonyOS应用程序框架——UIAbility实操

UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。 每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&…

12.Mysql 多表数据横向合并和纵向合并

Mysql 函数参考和扩展&#xff1a;Mysql 常用函数和基础查询、 Mysql 官网 Mysql 语法执行顺序如下&#xff0c;一定要清楚&#xff01;&#xff01;&#xff01;运算符相关&#xff0c;可前往 Mysql 基础语法和执行顺序扩展。 (8) select (9) distinct (11)<columns_name…

poe与chatgpt那个功能更强大

在当前的人工智能领域&#xff0c;Poe Al Chat以其卓越的聊天能力和实用的功能&#xff0c;受到了大家的广泛关注和喜爱。本文好为您个绍Poe Al Chat的功能&#xff0c;以及我们国内用户如何进行充值订阅。Poe Al Chat是一个基于OpenAl的GPT模型开发的人工智能聊天工具。它能够…

有限空间作业中毒窒息事故频发,汉威科技创新方案护航

工贸企业有限空间是我国重大事故多发频发的重点领域之一&#xff0c;安全问题形势严峻。 有限空间是指封闭或者部分封闭、未被设计为固定工作场所&#xff0c;人员可以进入&#xff0c;通风不良&#xff0c;易造成有毒有害物质、易燃易爆气体积聚或者氧含量不足的空间&#xf…