​Java基础复习笔记 ​第17章:反射机制#​

news2024/11/22 6:05:06

1. Class 的使用

  • 掌握:Class的理解
  • 掌握:获取Class的实例(前三种)
/*
* 获取Class实例的几种方式(掌握前三种)
* */
@Test
public void test1() throws ClassNotFoundException {
    //1.调用类的静态属性(.class)
    Class clazz1 = User.class;
    System.out.println(clazz1);

    //2. 通过对象调用getClass()
    User u1 = new User();
    Class clazz2 = u1.getClass();
    System.out.println(clazz2);

    System.out.println(clazz1 == clazz2); //true

    //3. 调用Class的静态方法forName(String className)
    Class clazz3 = Class.forName("com.atguigu02._class.User");
    System.out.println(clazz1 == clazz3);//true

    //4. (了解)使用类的加载器,调用loadClass(String className)
    Class clazz4 = ClassLoader.getSystemClassLoader().loadClass("com.atguigu02._class.User");
    System.out.println(clazz1 == clazz4);

}
  • 熟悉:Class可以指向哪些具体的结构?
    • 类、接口、注解、枚举、基本数据类型、数组、void等

2. 类的加载与类的加载器

  • 类的加载过程:
过程1:装载(Loading)
将类的class文件读入内存,并为之创建一个java.lang.Class对象。此过程由类加载器完成。

过程2:链接(Linking)
 ①验证Verify:确保加载的类信息符合JVM规范,例如:以cafebabe开头,没有安全方面的问题。
 ②准备Prepare:正式为类变量(static)分配内存并`设置类变量默认初始值`的阶段,这些内存都将在方法区中进行分配。
 ③解析Resolve:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。

过程3:初始化(Initialization)
  - 执行`类构造器<clinit>()方法`的过程。`类构造器<clinit>()方法`是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。
  - 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
  - 虚拟机会保证一个`类的<clinit>()方法`在多线程环境中被正确加锁和同步。
  • 了解:类的加载器
1. 常见的类的加载器
> 引导类加载器(Bootstrap ClassLoader):负责系统核心api的加载。
> 扩展类加载器(ExtClassLoader):jdk目录下的jre/lib/ext目录下的api
> 应用程序类加载器(或系统类加载器 AppClassLoader):用户自定义的类的默认的类的加载器

2. 相互之间的关系:不是继承关系。
但是我们经常说:应用程序类加载器的父类加载器是扩展类加载器;扩展类加载器的父类加载器是引导类加载器。
为什么习惯这样称谓呢?涉及到类的加载机制:双亲委派机制。


class SystemClassLoader{
    ExtClassLoader loader;
    public SystemClassLoader(ExtClassLoader loader){
        this.loader = loader;
    }
}

3.(掌握)使用类的加载器获取流,并读取配置文件信息
 /*
    * (掌握)使用类的加载器获取流,并读取配置文件信息
    * */
    @Test
    public void test3() throws Exception {

        Properties pros = new Properties();
        //方式1:默认的文件所在当前module下
//        FileInputStream is = new FileInputStream(new File("jdbc.properties"));
        FileInputStream is = new FileInputStream(new File("src/jdbc1.properties"));

        //方式2:默认的文件所在当前module的src下
//        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//        InputStream is = systemClassLoader.getResourceAsStream("jdbc1.properties");



        pros.load(is);

        String name = pros.getProperty("name");
        String password = pros.getProperty("password");
        System.out.println(name + ":" + password);


    }

3. 反射的应用1:创建运行时类的对象(掌握)

  • jdk8及之前:Class的newInstance()
1.1 如何实现?
调用Class的方法:newInstance(),返回一个运行时类的实例。

1.2 要想创建对象成功,需要满足:
> 对应的运行时类中必须提供一个空参的构造器
> 对应的运行时类的空参的构造器的访问权限必须够

1.3 回忆:JavaBean中要求给当前类提供一个公共的空参的构造器。有什么用?
> 子类继承父类以后,子类的构造器中在没有显式声明this(形参列表)或super(形参列表)的情况下,默认调用父类空参的构造器
> 提供空参的构造器,便于通过反射的方式动态的创建指定类的对象。


1.4 在jdk9中标识为过时,替换成什么结构:
clazz.getDeclaredConstructor().newInstance()进行替换。
  • jdk8之后:调用指定的构造器,设置构造器的访问权限,创建对象

4. 反射的应用2:获取运行时类的完整结构

  • 了解:获取所有的属性、所有的方法、所有的构造器、声明的注解等。
  • 熟悉:获取运行时类的父类、实现的接口们、所在的包、带泛型的父类、父类的泛型等

5. 反射的应用3:调用指定的属性、方法、构造器

(掌握)反射的应用3:调用指定的结构:指定的属性、方法、构造器

1.1 调用指定的属性:
步骤1:获取指定名称的属性:调用Class类中的getDeclaredField(String fieldName)
步骤2:确保此属性是可访问的:调用Field类中的setAccessible(true);
步骤3:获取此属性的值:调用Field类的get(Object obj)
      设置此属性的值:调用Field类的set(Object obj,Object fieldValue)

1.2 调用指定的方法
步骤1:获取运行时类中指明的方法:调用Class类的getDeclaredMethod(String methodName,Class ... paramTypes)
步骤2:确保此方法是可访问的:调用Method类中的setAccessible(true);
步骤3:调用此方法:调用Method类的invoke()方法,此方法的返回值即为invoke方法调用者对应的方法的返回值。

1.3 调用指定的构造器
步骤1:获取指定的构造器:调用Class类的getDeclaredConstructor(Class ... paramTypes)
步骤2:确保此构造器是可访问的:调用Constructor类中的setAccessible(true);
步骤3:调用此构造器,创建运行时类的对象:调用Constructor类中的newInstance(Object ... values);

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

略。为了后期学习框架做准备

7. 体会反射的动态性

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光伏储能EMS 风电智慧能量管理系统 -安科瑞王盼盼

安科瑞18721098782王盼盼 一&#xff1a;储能 EMS&#xff08;Energy Management System&#xff09; 储能 EMS&#xff1a;储能 EMS 是一个综合管理系统&#xff0c;用于整体管理和优化储能系统的运行。它基于电力系统的需求和需求响应&#xff0c;通过控制和协调储能设备的…

WPF中DataGrid实现多选框功能

1. 效果图 2. Model建立 public class RstModelCheck : ObservableObject {//为了显示Head1和Head2.而且View中绑定属性而非字段&#xff0c;否则不能显示。public string? Name { get; set; } public bool PlatenAll {get > _platenAll;set{SetProperty(ref _platenAl…

【代码随想录】【算法训练营】【第15天】 [102]二叉树的层序遍历 [226]翻转二叉树 [101]对称二叉树

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 15&#xff0c;一周中最困难的周三~ 题目详情 [102] 二叉树的层序遍历 题目描述 102 二叉树的层序遍历 解题思路 前提&#xff1a;二叉树的层级遍历 思路&#xff1a;利用队列的“先进先出…

C#利用WinForm实现可以查看指定目录文件下所有图片

目录 一、关于Winform 二、创建应用 三、功能实现 四、代码部分 一、关于Winform Windows 窗体是用于生成 Windows 桌面应用的 UI 框架。 它提供了一种基于 Visual Studio 中提供的可视化设计器创建桌面应用的高效方法。 利用视觉对象控件的拖放放置等功能&#xff0c;可…

信捷PLC 编程常用寄存器及编程技巧说明

最近在用信捷的PLC&#xff0c;分享下常用的寄存器和编程技巧说明。 技巧主要包括以下几个方面&#xff1a; 充分规划各个功能区&#xff1a;在编写程序时&#xff0c;需要充分规划各个功能区。 考虑伺服步进功能和气缸手动功能的应用&#xff0c;手动操作时&#xff0c;可…

C语言 | Leetcode C语言题解之第107题二叉树的层序遍历II

题目&#xff1a; 题解&#xff1a; int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {int** levelOrder malloc(sizeof(int*) * 2001);*returnColumnSizes malloc(sizeof(int) * 2001);*returnSize 0;if (!root) {return level…

个人感觉对Material设计有用的几个网址

(一) Modular and customizable Material Design UI components for Android GIthub: material-components-android (二) 学习Material设计 Material Design (三) 用于创建Material主题&#xff0c;支持导出多种格式 material-theme-builder

Web API——获取DOM元素

目录 1、根据选择器来获取DOM元素 2.、根据选择器来获取DOM元素伪数组 3、根据id获取一个元素 4、通过标签类型名获取所有该标签的元素 5、通过类名获取元素 目标&#xff1a;能查找/获取DOM对象 1、根据选择器来获取DOM元素 语法&#xff1a; document.querySelector(css选择…

一维前缀和[模版]

题目链接 题目: 分析: 因为要求数组中连续区间的和, 可以使用前缀和算法注意:下标是从1开始算起的, 真正下标0的位置是0第一步: 预处理出来一个前缀和数组dp dp[i] 表示: 表示[1,i] 区间所有元素的和dp[i] dp[i-1] arr[i]例如示例一中: dp数组为{1,3,7}第二步: 使用前缀数…

css特性(继承性、层叠性)

1.继承性 可以继承的常见属性&#xff08;文字控制属性都可以继承&#xff09; ps:可以通过调试器查看是否能够继承 注意&#xff1a;a标签的color会继承失效&#xff1b;h系列标签的font-size会继承失效 2.层叠性 后面的样式会覆盖前面的样式 给同一个标签设置不同的样式…

酷开科技以内容为契机,酷开系统向消费者需求的深度挖掘迈进一步

酷开系统还拥有强大的内容资源和推荐算法&#xff0c;能够根据消费者的兴趣爱好为其提供个性化的推荐服务。无论是电影、电视剧、综艺节目&#xff0c;还是新闻、体育、娱乐资讯&#xff0c;酷开系统都能帮助大家快速找到感兴趣的内容&#xff0c;并且通过智能推荐算法不断优化…

vue3插槽solt 使用

背景增加组件的复用性&#xff0c;个人体验组件化还是react 方便。 Vue插槽solt如何传递具名插槽的数据给子组件&#xff1f; 一、solt 原理 知其然知其所以然 Vue的插槽&#xff08;slots&#xff09;是一种分发内容的机制&#xff0c;允许你在组件模板中定义可插入的内容…

4月粽子行业线上市场销售数据分析

随着节日庆祝常态化&#xff0c;消费者对礼物消费的态度发生变化&#xff0c;这会影响粽子的消费模式和市场需求。再加上技术进步&#xff0c;如速冻粽子和真空粽子的推广&#xff0c;也极大地推动了粽子行业的发展&#xff0c;使得产品更易于保存和运输&#xff0c;从而满足了…

Spark-RDD-持久化详解

Spark概述 Spark-RDD概述 1.持久化与序列化的关系 在Spark中&#xff0c;持久化&#xff08;Persistence&#xff09;和序列化&#xff08;Serialization&#xff09;是两个关键概念&#xff0c;它们在RDD处理过程中起着重要作用&#xff0c;并且有一定的关联&#xff1a; &a…

Windows安装mingw32/w64

1.下载 MinGW-w64 WinLibs - GCCMinGW-w64 compiler for Windows Releases niXman/mingw-builds-binaries (github.com) MinGW-w64、UCRT 和 MSVCRT 是 Windows 平台上常用的 C/C 运行库&#xff0c;它们有以下不同点&#xff1a; MinGW-w64&#xff1a;是一个基于 GCC 的…

Transformer,革命性的深度学习架构

Transformer 是一种革命性的深度学习架构,专门设计用于处理序列数据,特别是在自然语言处理(NLP)任务中表现卓越。它由 Vaswani 等人在 2017 年发表的论文《Attention is All You Need》中首次提出,打破了当时基于循环神经网络(RNN)和卷积神经网络(CNN)的序列建模常规,…

Golang | Leetcode Golang题解之第108题将有序数组转换为二叉搜索树

题目&#xff1a; 题解&#xff1a; func sortedArrayToBST(nums []int) *TreeNode {rand.Seed(time.Now().UnixNano())return helper(nums, 0, len(nums) - 1) }func helper(nums []int, left, right int) *TreeNode {if left > right {return nil}// 选择任意一个中间位置…

基于Vue的图片文件上传与压缩组件的设计与实现

摘要 随着前端技术的发展&#xff0c;系统开发的复杂度不断提升&#xff0c;传统开发方式将整个系统做成整块应用&#xff0c;导致修改和维护成本高昂。组件化开发作为一种解决方案&#xff0c;能够实现单独开发、单独维护&#xff0c;并能灵活组合组件&#xff0c;从而提升开…

Leetcode861. 翻转矩阵后的得分

Every day a Leetcode 题目来源&#xff1a;861. 翻转矩阵后的得分 解法1&#xff1a;贪心 对于二进制数来说&#xff0c;我们只要保证最高位是1&#xff0c;就可以保证这个数是最大的&#xff0c;因为移动操作会使得它取反&#xff0c;因此我们进行行变化的时候只需要考虑首…

【Android安全】AOSP版本对应编号| AOSP版本适配Pixel或Nexus型号 | 驱动脚本下载地址

AOSP版本对应编号 https://source.android.com/docs/setup/about/build-numbers?hlzh-cn#source-code-tags-and-builds 例如android-8.1.0_r1 对应的编号是OPM1.171019.011 可以适配Pixel 2 XL AOSP驱动脚本下载 编译AOSP时&#xff0c;需要Google的驱动&#xff0c;后面才…