类的加载过程和反射以及注解

news2025/1/18 4:42:57

类的加载过程

三个阶段:加载-链接-初始化, 类的初始化只会执行1次。

加载

把字节码文件以流的形式加载到jvm中

链接

  1. 验证:验证字节码的合法性等以保证jvm的安全
  2. 准备:为静态变量赋予初始值,为静态常量赋予有效值。比如static int a = 1; static final int b = 2;
  3. 解析:将符号引用转换实际的地址引用

初始化

  1. 静态变量的直接显式赋值语句
  2. 静态代码块中的语句

在这里插入图片描述

注:代码里面声明某个类时,并不会马上初始化。

导致类初始化的几种情况

  1. 运行主方法所在的类,要先完成类初始化。
  2. 第一个使用某个类型,new这个类的实例对象。
  3. 调用某个类的静态成员或静态方法。
  4. 子类初始化时,父类还未初始化。
  5. 通过反射初始化某个类时,Class.forName("类的全名");

不会导致类初始化的操作

  1. 调用类的静态常量,比如static final int a = 3。
  2. 通过子类调用父类的静态变量,只有父类才会初始化。
  3. 使用某个类型创建数组对象时。比如B[] arr = new B[3];
  4. 使用某个类声明变量时不会初始化。

类加载器

类加载器分类

类的加载过程是通过类加载器完成的。

  • 引导类加载器(BootsrapClassLoader)
    • 主要加载jre/lib/rt目录下的jar包
    • 此类加载器是c/c++编写的
  • 扩展类加载器(ExtensionClassLoader)
    • 主要加载jre/lib/ext目录下的文件
    • 此类加载器ClassLoader的子类
  • 应用程序类加载器(ApplicationClassLoader)
    • 主要负责加载自己编写的代码编译后的字节码文件
    • 在classpath路径下的类
  • 自定义类加载器(SelfDefnitionClassLoader)
    • 加载指定路径下的类

获取类加载器

public class Demo{
	public static void main(String[] args){
		//1.通过类的Class实例获取
		ClassLoader classLoader = Demo.class.getClassLoader();
		System.out.println(classLoader);
	
		//2. 通过线程获取类加载器
		ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();
		System.out.println(classLoader1);
		
		//3. 通过ClassLoader的静态方法
		ClassLoader classLoader2 = ClassLoader.getSystemClassLoader();
	
		//4. 获取父级类加载器
		ClassLoader parent = classLoader.getParent();
		System.out.println("parent = " + parent);
		
	}
}

双亲委托机制

加载类时,先让自己的父类Extension ClassLoader去查看是否已经加载过,父类Extension ClassLoader接到委托后查询到未加载,先继续咨询父类Bootsrap ClassLoader来核实是否已经加载过。

在这里插入图片描述
作用:

  1. 避免重复加载已经加载过的类
  2. 防止有人通过类加载器注入恶意代码修改核心类

反射

Class实例

java创建了一个字节码类,表示所有的字节码文件。类加载器将字节码文件加载到jvm内存中时,相当于创建了字节码类的实例对象。该实例对象表示正在运行的java程序中的类和接口,该Class对象是唯一的。

获取Class实例的方法

  1. 类名.class
  2. Class.forName方法(后期框架最常用的方法)
  3. Object类的getClass方法
  4. ClassLoader的类加载器对象可以用系统类加载对象加载指定路径下的类型
//1. 类名.class
String.class;
//2.Class.forName
Class.forName("java.lang.String");
//3.Object类的getClass方法
new Student().getClass();
//4.通过类加载器的静态方法
ClassLoader.getSystemClassLoader().loadClass("java.lang.String");

反射的概念

不是通过类的对象实例来直接操作这个类的属性和方法,而是通过类的Class对象实例来获取这个类的属性和方法。这个就是反射,通过反射的方式来操作一个类。

获取类的构造器

public class Demo{
	public static void main(String[] args){
		//
		Class<?> clazz = Class.forName("java.lang.String");
		//获取所有public构造器
		clazz.getConstructors();
		//获取所有构造器,包括私有的
		clazz.getDeclaredConstructors();
		//获取指定的构造器
		Constructor<?> c = clazz.getConstructor();//根据构造器参数获取对应的构造器
		String s = c.newInstance();
		//获取有参构造器
		Constructor<?> c1= clazz.getConstructor(String.class);

		//获取私有方法需要先设置访问权限
		c1.setAccessible(true);
		//调用getDeclaredXX方法
		c1.getDeclaredContructor();
	}
}

获取类的属性

public class Demo{
	public static void main(String[] args){
		//
		Class<?> clazz = Class.forName("java.lang.String");
		//2. 获取所有声明的属性
		Field[] declaredFields = clazz.getDeclaredFields();
		//3.获取单个公共属性
		Object name= clazz.getField("name");
		Object obj = clazz.newInstance();//创建Student对象
		//获取obj的name属性值
		Object value = name.get
	}
}

创建任意引用类型的对象

  1. 直接通过Class对象来实例化(要求必须有无参构造)
  2. 通过获取构造器对象来进行实例化
  • 方式1:
    • 获取该类型的Class对象Class.forName()
    • 创建对象clazz.newInstance()
  • 方式2:
    • 获取该类型的Class对象Class.forName()
    • 获取构造器对象clazz.getDeclaredConstructor()
    • 创建实例对象contructor.newInstance()

操作任意类型的属性

  • 获取该类型的Class对象
  • 获取属性对象Field field = clazz.getDeclaredField("username");
  • 访问私有属性时,需要设置属性可访问setAccessilbe(true)
  • 创建实例对象:如果操作的是非静态属性,需要创建实例对象Object obj = clazz.newInstance();
  • 设置属性值 field.set(obj, "chai");
  • 获取属性值Object value = field.get(obj);

调用任意类型的方法

  1. 获取该类型的Class对象clazz
  2. 获取方法对象method = getDeclaredMethod(方法名, 参数列表)
  3. 创建实例对象clazz.newInstance()
  4. 调用方法 method.invoke(obj, 参数)

注解

注解也是一种注释,它不会改变程序原有的逻辑,只是对程序增加了某些注释性信息。不过它不同于单行注释和多行注释,对于单行注释和 多行注释是给程序员看的,而注解是可以被编译器或其他程序读取的一种注释,程序还可以根据注解的不同,做出相应的处理。注解是插入到代码中便于现有工具对它们进行处理的标签。

注解的作用

  1. 编写文档,注解可以生成文档
  2. 代码分析, 比如注解的反射
  3. 编译检查,比如@Override

常见注解:

注解名称作用
@author标识作者名
@version标识版本号
@Override表示该方法是重写方法
@Deprecated表示过时的
@SupressWarning抑制警告

自定义注解

public @interface MyAnno{
	String value() default "java";//注解的属性
	int num() default 1;
	int[] nums();
}
  • 定义了默认值时,注解使用时就可以不给对应的属性值赋值了。
  • 如果只是给value属性赋值,可以省略value = ,直接写成@MyAnno("hello")

元注解

  • @Target(ElementType.TYPE):表示注解可以使用的位置
    • TYPE:类
    • FIELD:属性
    • METHOD:方法
  • @Retentioin():表示注解的有效周期
    • SOURCE:在源码中有效
    • CLASS:在字节码中有效
    • RUNTIME:运行期间有效
  • @Documented:表示注解信息可以提取到文档当中
  • @Inherited:表示注解信息可以被继承

注解的解析

通过Java技术获取注解数据的过程则称为注解解析。通常通过反射获取注解及其属性值。

public class TestAnnotation {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> clazz = Class.forName("com.d8_18._03anatation.exer.BookStore");

        Book book = clazz.getAnnotation(Book.class);
        String value = book.value();
        double price = book.price();
        String[] authors = book.authors();
        System.out.println("authors = " + authors);
        System.out.println("price = " + price);
        System.out.println("value = " + value);
    }
}

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

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

相关文章

【FusionInsight 问题】FusionInsight HD 6.5.1 集群中遇到的问题(01)

FusionInsight HD 6.5.1 集群中遇到的问题&#xff08;01&#xff09; FusionInsight HD 6.5.1 集群中遇到的问题&#xff08;01&#xff09;Spark-on-HBase认证问题Failed to find any Kerberos tgt服务端配置修改客户端配置修改 Spark-on-HBase依赖包问题phoenix-core-4.13.1…

2023年CRM系统排行榜

很多企业想要选择一款CRM系统来进行管理&#xff0c;提高效率。那么&#xff0c;2023年国内有哪些优秀的CRM系统呢&#xff1f;这里有一份2023最新国内crm系统排名&#xff0c;希望可以帮助到正在选型的您。 1、Zoho CRM Zoho CRM是一款知名的SaaS云端CRM系统&#xff0c;拥有…

使用 OpenTelemetry 构建可观测性 02 - 埋点

这是讲解 OpenTelemetry 系列博客的第二篇。在上一篇博客中&#xff0c;我们介绍了 OpenTelemetry 是什么以及由什么组成。现在我们将讨论如何使用 OTel 准确收集遥测数据和链路追踪数据。 手动埋点 我们这里谈论“埋点”(代码插桩)&#xff0c;是指通过技术手段采集链路追踪…

网络协议详解之BGP

目录 BGP&#xff08;边界网关路由协议&#xff09; 一、基础知识囊括&#xff1a; 1.1 IGP协议追求&#xff1a; 1.2 EGP协议的追求&#xff1a; 二、BGP特点&#xff1a; 2.1 BGP数据包 2.2 BGP的工作过程 2.3 结构突变** 2.4 名词解析 2.5 BGP的路由黑洞问题 2.6 …

Plecs电力电子仿真专业教程-第一季 第四节 C语言脚本模块介绍

Plecs电力电子仿真专业教程-第一季 目录 第一章 Plecs是什么 第二节 Plecs 的功能介绍 第三节 Plecs界面介绍 补充课程 Plecs的安装教程与软件下载 第四节 Plecs C语言脚本模块介绍 鉴于很多学习的小伙伴私信我要安装软件&#xff0c;特此添加如下链接&#xff1a; Plecs4.6…

我记不住的Linux那些时间及区别

背景&#xff1a;总是搞不明白Linux系统中这些相关的时间及区别&#xff0c;通过查看网上的资料发现很多都是人云亦云&#xff0c;没有任何新意&#xff0c;所以这里根据自己的试验及资料&#xff0c;再次总结一下&#xff0c;在这里记录一下。 一、介绍 标准的POSIX文件有三…

spring如何进行依赖注入,通过set方法把Dao注入到serves

1、选择Generate右键鼠标 你在service层后面方法的这些: 2、UserService配置文件的写法是怎样的&#xff1a; 3、我们在UserController中执行一下具体写法&#xff1a; 最后我们执行一下 &#xff1a; 4、这里可能出现空指针&#xff0c;因为你当前web层,因为你new这个对象根…

计算机竞赛 医学大数据分析 - 心血管疾病分析

文章目录 1 前言1 课题背景2 数据处理3 数据可视化4 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的心血管疾病分析 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9…

神经网络为什么可以学习

本资料转载于B站up主&#xff1a;大模型成长之路,仅用于学习和讨论&#xff0c;如有侵权请联系 动画解析神经网络为什么可以学习_哔哩哔哩_bilibilis 1、一个神经网络是由很多神经元形成的 1.1 也可以是一层&#xff0c;也可以是多层 2 层和层之间的连接就跟一张网一样 2.1 每…

AutoCompany模型的概念设计,涵盖了AI智能公司的各个角色

AutoCompany模型的概念设计&#xff0c;涵盖了AI智能公司的各个角色 自动化企业概念设计与设想&#xff0c;文本将介绍AutoCompany模型的概念设计&#xff0c;涵盖了AI智能公司的各个角色&#xff0c;并结合了GPT-4接口来实现各个角色的功能&#xff0c;设置中央控制器&#xf…

【Redis】Redis哨兵模式

【Redis】Redis哨兵模式 Redis主从模式当主服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服务器&#xff0c;需要人工干预费事费力&#xff0c;为了解决这个问题出现了哨兵模式。 哨兵模式是是一个管理多个 Redis 实例的工具&#xff0c;它可以实现对 Redis 的监控…

动力电池系统介绍(十三)——高压互锁(HVIL)

动力电池系统介绍&#xff08;十三&#xff09; 一、高压互锁梗概1.1 高压互锁原理1.1 高压互锁内部结构1.2 高压互锁分类1.3 高压互锁原则 二、高压互锁常见故障2.1 高压互锁开关失效2.2 端子退针导致开路2.3 互锁端子对地短路2.4 动力电池内部故障 三、高压互锁故障排查 一、…

孟德尔随机化:Steiger Test避免反向因果关系

Steiger Test避免反向因果关系 以下steiger test方法是一个新的方法学&#xff0c;增加后提升提取工具变量的稳健性&#xff0c;没有的话也不影响文章内容。 看自己的需要。跑分析过程中&#xff0c;如果是GWAS数据没有samplesize&#xff0c;自己又需要这个内容&#xff0c;…

musl libc ldso 动态加载研究笔记:01

前言 musl 是一个轻量级的标准C库&#xff0c;建立在系统调用之上&#xff0c;可以认为是【用户态】的C 库&#xff0c;与 glibc 或者 uClibc 属于同一类。 基于 musl 的 gcc 工具链包括交叉编译工具链&#xff0c;可以用于编译 Linux 或者其他的操作系统&#xff0c;如当前 L…

kubesphere 集成 sonar

文章目录 安装 helm通过 helm 安装 sonar配置 SonarQube 服务器创建 SonarQube 管理员令牌SonarQube 配置添加到 ks-installer创建 Webhook 服务器将 SonarQube 服务器添加至 Jenkins将 sonarqubeURL 添加到 KubeSphere 控制台重启服务 为新项目创建 SonarQube Token 官方文档&…

蓝蓝设计-ui设计公司-界面设计案例作品

泛亚高科-光伏电站控制系统界面设计 html前端 | 交互设计 | 视觉设计 | 图标设计 泛亚高科(北京)科技有限公司&#xff08;以下简称“泛亚高科”&#xff09;&#xff0c;一个以实时监控、高精度数值计算为基础的科技公司&#xff0c; 自成立以来&#xff0c;组成了以博士、硕…

同样都是找工作,为什么你的简历没人看?

上次的文章分享了自己软件测试面试时的一些经历&#xff0c;今天我想分享一下自己当时写简历以及投简历方面的经历&#xff0c;本文内容纯粹是个人简单分享&#xff0c;如果有写得不好的地方还请读者包涵与指正。 我是去年的九月初开始投递简历的&#xff0c;貌似各行各业的人…

μCOS-Ⅲ_简介

μCOS-Ⅲ简介 文章目录 μCOS-Ⅲ简介前言一、什么是 C/OS-III&#xff1f;二、C/OS-III的特点三、C/OS-III的版本和参考资料1、C/OS-III版本2、C/OS-III源码获取3、C/OS-III参考资料 四、C/OS-III源码简介总结 前言 μcos-III是一个可以基于ROM运行的、可裁剪的、抢占式、实时…

第五章.编辑资料

5.1.添加编辑页面 <template><div class="users-show"><div class="col-md-3 main-col"><div class="box"><div class="padding-md"><div class="list-group text-center"><rou…

k8s v1.27.4 部署metrics-serverv:0.6.4,kube-prometheus

只有一个问题&#xff0c;原来的httpGet存活、就绪检测一直不通过&#xff0c;于是改为tcpSocket后pod正常。 wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml修改后的yaml文件&#xff0c;镜像修改为阿里云 apiVersion: …