【 java 反射上篇】java反射机制不难吧?来看看这篇

news2024/11/22 1:35:07

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:java 小白到高手的蜕变🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥
    请添加图片描述

目录

    • 📋 个人简介
  • 前言
    • 反射的概述
    • java反射机制提供的功能
    • java反射相关的主要API
    • Class类的理解
    • 获取Class实例的4种方式
    • 哪些类型可以有Class对象
    • 理解类的加载过程
    • ClassLoader类加载器的理解
  • 结语

前言

本节将学习java中的反射,上篇主要讲解一些概念以及一些需要了解的东西,下篇我将总结如何使用反射调用类的内部结构!

反射的概述

  • 反射是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API 取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
  • 加载完类之后,在堆内存的方法区中就产生了一个 Class 类型的对象(一个类只有一个 Class 对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

java反射机制提供的功能

>在运行时判断任意一个对象所属的类
>在运行时构造任意一个类的对象
>在运行时判断任意一个类所具有的成员变量和方法
>在运行时获取泛型信息
>在运行时调用任意一个对象的成员变量和方法
>在运行时处理注解
>生成动态代理

java反射相关的主要API

java.lang.Class :代表一个类
java.lang.reflect.Method :代表类的方法
java.lang.reflect.Field :代表类的成员变量
java.lang.reflect.Constructor :代表类的构造器

Class类的理解

1.类的加载过程:

程序经过 javac.exe 命令以后,会生成一个或多个字节码文件(. class 结尾)。接着我们使用 java.exe 命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此运行时类,就作为 Class 的一个实例。

2.换句话说, Class 的实例就对应着一个运行时类。
3.加载到内存中的运行时类,会缓存一定的时间,在此时间之内,我们可以通过不同的方式来获取此运行时类。

获取Class实例的4种方式

首先我们随便创建一个类,然后我们用四种不同的方式来获取这个类的Class实例。

public class People {
    String name;
    int age;

    public People(){

    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

四种方式:

package java反射;

/**
 * @Author:Aniu
 * @Date:2023/1/14 19:00
 * @description TODO
 */
public class Demo {
    public static void main(String[] args) {
        // 获取Class实例的4种方式
        // 方式一: 调用运行时类的属性 .class
        Class cl1 = People.class;
        System.out.println(cl1);
        // 方式二 :通过运行时类的对象
        People p = new People();
        Class cl2 = p.getClass();
        System.out.println(cl2);
        // 方式三:调用Class的静态方法 forName(String classPath)
        try {
            Class cl3 = Class.forName("java反射.People");
            System.out.println(cl3);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 方式四:使用类的加载器:ClassLoader (了解)
        ClassLoader classLoader = People.class.getClassLoader();
        try {
            Class cl4 = classLoader.loadClass("java反射.People");
            System.out.println(cl4);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
从使用频率上来说,第三种最常用,包括我们看到的JDBC数据库连接中也是使用了第三种!

哪些类型可以有Class对象

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

	Class c1= Object.class;
	Class c2= Comparable.class; // 接口
	Class c3= String[].class;
	Class c4= int[][].class;
	Class c5= ElementType.class; //枚举
	Class c6= Override.class; //注解
	Class c7= int.class;
	Class c8= void.class;
	Class c9= Class.class;
	// 输出c1-c9
	Class[] clas = new Class[]{c1,c2,c3,c4,c5,c6,c7,c8,c9};
	for(Class item: clas){
	    System.out.println(item);
	}
	
	int[] a = new int[10];
	int[] b = new int[100];
	Class c10 = a.getClass();
	Class c11 = b.getClass();
	//只要元素类型与维度一样,就是同一个 Class
	System.out.println(c10==c11);

在这里插入图片描述

理解类的加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化
请添加图片描述

  • 加载:将 class 文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的 java.lang.Class 对象,作为方法区中类数据的访问入口(即引用地址)。所有需要访问和使用类数据只能通过这个 Class 对象。这个加载的过程需要类加载器参与。

  • 链接:将 Java 类的二进制代码合并到 JVM 的运行状态之中的过程。
    >验证:确保加载的类信息符合 JVM 规范,例如:以 cafe 开头,没有安全方面的问题
    >准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。
    >解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。

  • 初始化:
    >执行类构造器 <clinit >() 方法的过程。类构造器 <clinit >() 方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。
    >当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
    >虚拟机会保证一个类的 <clinit >() 方法在多线程环境中被正确加锁和同步。

在这里插入图片描述

ClassLoader类加载器的理解

请添加图片描述
这张图是java语言执行的过程,其中就有类加载器(或者类装载器)。

类加载器的作用:

  • 类加载的作用:将 class 文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的 java.lang.Class 对象,作为方法区中类数据的访问入口。
  • 类缓存:标准的 JavaSE 类加载器可以按要求查找类,但一旦某个类被加载到类加载器中,它将维持加载(缓存)一段时间。不过 JVM 垃圾回收机制可以回收这些 Class 对象。

JVM规范定义了以下类型的类的加载器:
请添加图片描述

	//对于自定义类,使用系统类加载器进行加载
	ClassLoader classLoader = People.class.getClassLoader ();
	System.out.println (classLoader);
	//调用系统类加载器的 getParent():获取扩展类加载器
	ClassLoader classLoader1 = classLoader.getParent();
	System.out.println(classLoader1);
	//调用扩展类加载器的 getParent():无法获取引导类加载器
	//引导类加载器主要负责加载 java 的核心类库,无法加载自定义类的。
	ClassLoader classLoader2 = classLoader1.getParent();
	System.out.println(classLoader2);
	//String是由引导类加载器加载的,无法获取
	ClassLoader classLoader3 = String.class.getClassLoader ();
	System.out.println(classLoader3);

在这里插入图片描述
使用ClassLoader也可以加载配置文件,这里不再总结,感兴趣的可以去了解以下!

结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门

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

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

相关文章

BMS系统—产生原因如何工作

1 为什么需要BMS系统 1.1 介绍 1&#xff09;BMS&#xff0c;battery management system,电池管理系统 2&#xff09;BMS是一套嵌入式系统&#xff0c;由硬件和软件共同组成 3&#xff09;BMS功能&#xff1a;管理多节锂电池组成的电池包&#xff0c;实现充放电管理、安全保护…

jsp动物园网上购票系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 动物园网上购票系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统采用web模式开发&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#x…

Python:每日一题之FBI树(深度优先遍历)

题目描述 我们可以把由 “0” 和 “1” 组成的字符串分为三类&#xff1a;全 “0” 串称为 B 串&#xff0c;全 “1” 串称为 I 串&#xff0c;既含 “0” 又含 “1” 的串则称为 F 串。 FBI树是一种二叉树&#xff0c;它的结点类型也包括 F 结点&#xff0c;B 结点和 I 结点…

Anolis 8.6 部署 Kafka 3.3.1 安装和测试

龙蜥 8.6 安装 Kafka 3.3.1 并通过 SpringBoot 3.0.1 版本调试一.Kafka 安装1.下载编译后的文件2.拷贝到 Anolis 并解压3.启动服务3.常用命令1.Topic 增查删2.生产消费测试二.SpringBoot 连接 Kafka1.项目结构、依赖、配置文件和启动类2.生产者和生产监听3.消费者和消费监听4.自…

【Java寒假打卡】Java基础-并发工具类

【Java寒假打卡】Java基础-并发工具类HashMap在多线程下的问题ConcurrentHashMapCountDownLatchHashMap在多线程下的问题 package com.hfut.edu.test14;import com.sun.jdi.request.StepRequest;import java.util.HashMap;public class test2 {public static void main(String…

信号的时域和频域特性的区别到底是什么?

不严谨的说&#xff0c;时域和频域分析就是在不同的空间看待问题的&#xff0c;不同空间所对应的原子(基函数)是不同的。你想一下时域空间的基函数是什么&#xff1f;频域空间的基函数是什么&#xff1f;一般的时-频联合域空间的基函数是什么&#xff1f;小波域空间的基函数是什…

线索二叉树(c++)

1.引言&#xff1a; 二叉树的三种遍历方法能将二叉树中的结点按某种方式生成一个线性序列&#xff0c;能将一个非线性结构进行线性化操作。但随之也产生两个问题&#xff1a; 遍历效率低 在采用左右链表示方法作为二叉树的存储结构时&#xff0c;当二叉树更新后&#xff0c;并…

【博客586】ipvs的hook点位置以及hook点钩子函数剖析

ipvs的hook点位置以及hook点钩子函数剖析 ipvs实现负载均衡的基础 ipvs其实是基于netfilter框架来挂载hook点&#xff0c;从而对流量进行dnat等操作 ipvs的hook点剖析 IPVS的实现利用了Netfilter的三个Hook点&#xff0c;分别是&#xff1a;NF_INET_LOCAL_IN、NF_INET_LOCAL_O…

【nvidia CUDA 高级编程】NVSHMEM 直方图——复制式方法

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

pandas时间序列,案列

一&#xff1a;pandas时间序列 1.1为什么要学习pandas中的时间序列 不管在什么行业&#xff0c;时间序列都是一种非常重要的数据形式&#xff0c;很多统计数据以及数据的规律也都和时间序列有着非常重要的联系&#xff0c;而且在pandas中处理时间序列是非常简单的 1.2生成一段时…

【Python技巧】:cmd查看Python版本号居然与自己电脑装的版本不一致,特此提出解决方案

项目场景&#xff1a; 大家好&#xff01;欢迎大家看我的博客&#xff0c;最近学习Python的GUI&#xff08;PyQt5&#xff09;的时候发现了自己电脑的一个python问题&#xff0c;我本想装一下PyQt5&#xff0c;顺手查了一下自己电脑的Python版本&#xff0c;没想到居然是Python…

哈希表(二)—— 开散列 / 拉链法 / 哈希桶的模拟实现

哈希表的基本思路是通过某种方式将某个值映射到对应的位置&#xff0c;这里的采取的方式是除留余数法&#xff0c;即将原本的值取模以后再存入到数组的对应下标&#xff0c;即便存入的值是一个字符串&#xff0c;也可以根据字符串哈希算法将字符串转换成对应的ASCII码值&#x…

Week 6 hw3-1 全连接网络反向传播推导

Week 6 hw3-1 全连接网络反向传播推导 折腾了半天&#xff0c;记录一下。 作业中网络由若干全连接层ReLU组成&#xff0c;输出层的函数为softmax&#xff0c;损失函数为交叉熵。 一、记号 设网络有nnn层。如图&#xff0c;当i<ni<ni<n时&#xff0c;我们有如下几条…

机器学习/人工智能 实验一:典型监督学习方法分类实践与比较分析

一、实验目的与要求 (1)利用所学习的监督学习方法完成目标识别实验方案的设计。 (2)编程并利用相关软件完成实验测试&#xff0c;得到实验结果。 (3)通过对实验数据的分析﹑整理&#xff0c;方法的对比&#xff0c;得出实验结论&#xff0c;培养学生创新思维和编写实验报告的能…

【PyTorch深度学习实践】09_卷积神经网络基础

文章目录1.卷积操作1.1 卷积操作1.2 padding-填充1.3 stride-步长1.4 pooling-池化1.5 基础版CNN代码示例1.6 完整CNN代码示例1.卷积操作 卷积神经网络概览 1.1 卷积操作 输入通道数卷积核通道数&#xff0c;卷积核个数输出通道数 1.2 padding-填充 padding是为了让源图像最…

FPGA图像处理HLS实现三种图像缩放算法,线性插值、双线性插值、双三次插值,提供HLS工程和vivado工程源码

目录一、三种图像缩放算法介绍线性插值双线性插值双三次插值二、HLS实现线性插值图像缩放三、HLS实现双线性插值图像缩放四、HLS实现双三次插值图像缩放五、HLS在线仿真并导出IP六、其他FPGA型号HLS在线仿真并导出IP七、zynq7100开发板vivado工程八、上板调试验证九、福利&…

纪念QT可直接安装的离线版最后版本5.14.2

为什么说纪念呢&#xff1f;因为&#xff0c;这个版本之后再也没有可下载下来安装的版本了&#xff0c;因为我们以后再也没有这么方便了。为是很么说纪念呢&#xff1f;因为我们从QT还很柔弱的时候开始就是使用的离线版。 以前用c#来做组态&#xff0c;自定义控件开发起来也还…

基础知识一览2

这里写目录标题1.XML2.1 XML中的转义字符2.2 CDATA区2.3 如何去约束XMl:DTD2.3.1 xml文件内部引用DTD约束2.3.2 xml文件引用外部DTD约束2.3.3 xml文件引用公共DTD约束1.XML xml的文件后缀名是.xmlxml有且只有一个根标签xml的标签是尖括号包裹关键字成对出现的&#xff0c;有开…

如何做好banner设计(banner设计要点包括哪些)

网页设计的Banner作为表达网站价值或者传达广告信息的视觉主体&#xff0c;一直在根据网络环境的变化而变化着&#xff0c;从表现形式到尺寸大小&#xff0c;再到创意的多元化&#xff0c;因此更需要我们网页设计师们对其设计创意进行丰富和完善&#xff0c;才能真正达到宣传的…

Elasticsearch入门——Elasticsearch7.8.0版本和Kibana7.8.0版本的下载、安装(win10环境)

目录一、Elasticsearch7.8.0版本下载、安装1.1、官网下载地址1.2、下载步骤1.3、安装步骤(需要jdk11及以上版本支持)1.4、启动后&#xff0c;控制台中文乱码问题解决二、Node下载、安装&#xff08;安装Kibana之前需要先安装Node&#xff09;2.1、Node官网下载地址2.2、Node下载…