java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
Class
- Class常用方法
- 获取Class对象六种方式
- 哪些类型有Class对象
- 动态和静态加载
- 类加载流程
- 加载阶段
- 连接阶段
- 连接阶段-验证
- 连接阶段-准备
- 连接阶段-解析
- 初始化阶段
- 获取类结构信息
Class常用方法
第一步:创建一个实体类
public class Car {public String brand = "宝马";public int price = 500000;public String color = "白色";@Overridepublic String toString() {return "Car{" +"brand='" + brand + '\'' +", price=" + price +", color='" + color + '\'' +'}';}
}
第二步:常用方法的演示
public class Class02 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {String classAllPath = "Reflection.Car";//获取到Car类 对应的 Class对象//<?> 表示不确定的Java类型Class<?> cls = Class.forName(classAllPath);//输出clsSystem.out.println(cls); //显示cls对象,是哪个类的Class对象 class Reflection.CarSystem.out.println(cls.getClass());//输出cls运行类型 class java.lang.Class//得到包名System.out.println(cls.getPackage().getName());//包名//得到全类名System.out.println(cls.getName());//通过cls创建对象实例Car car = (Car)cls.newInstance();System.out.println(car);//通过反射获取属性 brandField brand = cls.getField("brand");System.out.println(brand.get(car));//宝马//通过反射给属性赋值brand.set(car,"奔驰");System.out.println(brand.get(car));//奔驰//得到所有的属性(字段)Field[] fields = cls.getFields();for(Field f:fields){System.out.println(f.getName());//名称}}
}
运行结果:

获取Class对象六种方式
第一种:在已知一个类的全类名,且该类在类的路径下,可通过Class类的静态方法Class.forName()获取(多用于配置文件,读取全类路径,加载类)
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//1.Class.forNameString classAllPath = "Reflection.Car";//通过读取配置文件获取Class<?> cls1 = Class.forName(classAllPath);}
}
第二种:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//2.类名.class,应用场景:用于参数传递Class cls2 = Car.class;}
}
第三种:若已知某个类的实例,调用该实例的getClass()方法获取Class对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//3.对象.getClass(),应用场景:有对象实例Car car = new Car();Class cls3 = car.getClass();}
}
第四种:通过类加载器来获取到类的Class对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {//4.通过类加载器[4种]来获取到类的Class对象String classAllPath = "Reflection.Car";//(1)先得到类加载器 carClassLoader classLoader = car.getClass().getClassLoader();//(2)通过类加载器得到Class对象Class<?> cls4 = classLoader.loadClass(classAllPath);}
}
基本数据类型按如下方式得到Class类对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {Class<Integer> integerClass = int.class;Class<Character> characterClass = char.class;Class<Boolean> booleanClass = boolean.class;}
}
基本数据类型对应的包装类,可以通过.TYPE得到Class类对象
public class GetClass_ {public static void main(String[] args) throws ClassNotFoundException {Class<Integer> type1 = Integer.TYPE;Class<Character> type2 = Character.TYPE;}
}
哪些类型有Class对象
1.外部类,成员内部类,静态内部类,局部内部类,匿名内部类
2.interface:接口
3.数组
4.enum:枚举
5.annotation:注解
6.基本数据类型
7.void
动态和静态加载
反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载
1.静态加载:编译时加载相关的类,如果没有则报错,依赖性太强
假设我现在在代码里面放了一个没有创建的Dog类
public class ClassLoad_ {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入key");String key = sc.next();switch (key){case "1":Dog dog = new Dog();dog.cry();break;case "2":System.out.println("ok");break;default:System.out.println("do nothing");}}
}
导致在编译的时候就发生了报错,虽然我们在运行的时候不一定会使用到,因为new Dog()是静态加载,因此必须编写Dog

2.动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类,则不报错,降低了依赖性
public class ClassLoad_ {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {Scanner sc = new Scanner(System.in);System.out.println("请输入key");String key = sc.next();switch (key){case "1":break;case "2":Class cls = Class.forName("Person");//加载Person类Object o = cls.newInstance();Method m = cls.getMethod("hi");m.invoke(o);System.out.println("ok");break;default:System.out.println("do nothing");}}
}
因为反射是动态加载,可以通过编译,只有在运行的时候才会报错,Person类是动态加载,所以,没有编写Person类也不会报错,只有动态加载该类的时候才会报错

1.当创建对象时(new) //静态加载
2.当子类被加载时,父类也加载 //静态加载
3.调用类中的静态成员时//静态加载
4.通过反射//动态加载
类加载流程


加载阶段
JVM在该阶段的主要目的是将字节码从不同的数据源(可能是class文件、也可能是jar包,甚至网络)转化为二进制字节流加载到内存中,并生成一个代表该类的java.long.Class对象
连接阶段
连接阶段-验证
目的是为了确定文件中字节流包含的信息符合当前虚拟机的要求,并且不会危害安全,可以考虑使用-Xverify:none参数来关闭大部分的类验证措施,缩短虚拟机类加载的时间

连接阶段-准备
JVM会在该阶段对静态变量,分配内存默认初始化(对应数据类型的默认初始值,如0、0L、null、false等)。这些变量所使用的内存都将在方法区中进行分配(常量和静态变量不一样,因为一旦赋值就不变,它直接就是它对应的值)
连接阶段-解析
虚拟机将常量池的符号引用替换为直接引用的过程中,在编译的过程中因为没有实际的内存地址,所以只能用符号的方法来记录,当加载好之后用地址来替换
初始化阶段
到初始化阶段,才真正开始执行类中定义的java程序代码,此阶段是执行()方法过程()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并进行合并
示例代码:
public class ClassLoad03 {public static void main(String[] args) {//1.加载B类,并生成B的class对象//2.连接 num = 0;//3.初始化阶段// 依次自动收集类中的所有静态变量的赋值动作和静态代码快的语句/*
* clinit(){
* System.out.println("B 静态代码快被执行");
* num = 300;
*
* 合并:num=100}*/new B(); System.out.println(B.num);}
}
class B{static {System.out.println("B 静态代码快被执行");num = 300;}static int num = 100;public B(){System.out.println("B() 构造器被执行 "+num);}
}
运行结果:

如果直接使用类的静态属性,也会导致类的加载
注:
虚拟机保证一个类的()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都需要阻塞等待,直到线程执行()方法完毕
获取类结构信息

public class ReflectionUtils {public static void main(String[] args) throws ClassNotFoundException {api_01();}//第一组方法APIpublic static void api_01() throws ClassNotFoundException {//得到Class对象Class<?> personCls = Class.forName("Reflection.com.hspedu.classload.Person");//获取全类名System.out.println(personCls.getName());//获取简单类名System.out.println(personCls.getSimpleName());//获取所有public修饰的属性,包含本类及父类Field[] fields = personCls.getFields();for (Field field : fields) {System.out.println("本类及父类属性="+field.getName());}//获取本类中所有属性Field[] declaredFields = personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("本类中所有的属性="+declaredField.getName());}//获取所有public修饰的方法,包含本类以及父类Method[] methods = personCls.getMethods();for (Method method : methods) {System.out.println("本类以及父类的方法="+method.getName());}//获取本类所有的方法Method[] declaredMethods = personCls.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println("本类所有方法="+declaredMethod.getName());}//获取所有public修饰的构造器,包含本类Constructor<?>[] constructors = personCls.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println("本类以及父类的构造器="+ constructor.getName());}//获取本类所有的构造器Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("本类所有的构造器"+declaredConstructor.getName());}//以Package形式返回包信息System.out.println(personCls.getPackage());//以Class形式返回父类信息System.out.println("父类的class对象"+personCls.getSuperclass());//以Class[]形式返回接口信息Class<?>[] interfaces = personCls.getInterfaces();for (Class<?> anInterface : interfaces) {System.out.println("接口信息="+anInterface.getName());}//返回注解信息Annotation[] annotations = personCls.getAnnotations();for (Annotation annotation : annotations) {System.out.println("注解信息="+annotation);}}
}
interface IA{}
interface IB{}
class A{public String hobby;public void hi(){}public A(){}
}
@Deprecatedclass Person extends A implements IA,IB{public Person(){}public Person(String s){ }private Person(String name,int age){}//属性public String name;protected int age;String job;private double sal;//方法public void m1(){}protected void m2(){}void m3(){}private void m4(){}}

public class ReflectionUtils {public static void main(String[] args) throws ClassNotFoundException {api_02();}public static void api_02() throws ClassNotFoundException {//得到Class对象Class<?> personCls = Class.forName("Reflection.com.hspedu.classload.Person");//获取本类所有属性Field[] declaredFields = personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("本类中的所有属性="+declaredField.getName()+" 该属性的修饰符值="+declaredField.getModifiers()+" 该属性的类型="+declaredField.getType());}}
}
interface IA{}
interface IB{}
class A{public String hobby;public void hi(){}public A(){}
}
@Deprecatedclass Person extends A implements IA,IB{public Person(){}public Person(String s){ }private Person(String name,int age){}//属性public String name;protected static int age;String job;private double sal;//方法public void m1(){}protected void m2(){}void m3(){}private void m4(){}}

相关文章:
java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步:创建一个实体类 public class Car {public String brand "宝…...
【数据结构】线性表和顺序表
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线…...
Ubuntu数据库安装(mysql)
##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...
MyBatis-Plus的入门学习
MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法:update乐观锁select查所有根据id查多个id批量查询简单条件查询(通…...
华为OD机试题 - 内存池(JavaScript)
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...
数据库索引原理
数据库索引的作用是做数据的快速检索,而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引,但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树:二叉树中,左子树比根节点小&a…...
字符函数和字符串函数详解(1)
目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态,写的文章质量不佳让大家失望,我现在也在反思我在做什么,我会什么,我学了什么。等我想明白的那天,我一定能跟大家顶峰相见的&a…...
【数据分析:工具篇】NumPy(1)NumPy介绍
【数据分析:工具篇】NumPy(1)NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy(Numerical Python)是Python的一个开源的科学计算库,它主要用于处理大规模的多维数组…...
mysql时区问题
设置mysql容器时间与服务器时间一致 问题背景: 今天测试发现一个问题,时间不一致,当工单入库时,其创建时间和更新时间应该是一样的,即使不一样最多只会错几秒的时间;实际上两个时间相差的大概8小时&#…...
磨金石教育摄影技能干货分享|高邮湖上观花海
江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩࿰…...
mysql navicat忘记密码
mysql忘记密码是常用的事情,那么如何解决它呢?1、首先将MySQL的服务关闭,两种方法:(1)打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。(2)打开任务管理器,找到服…...
Git的下载、安装、配置、使用、卸载
前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站:https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记:https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...
【博客631】监控网卡与进程网络IO使用情况
监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息,因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息: # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...
【Leetcode】【简单】35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...
sql面试题
mysql优化 优化准则: 建表时:合理选择字段的类型,单表字段数量 sql查询尽量单表操作,避免复杂操作,复杂的多表通过java代码实现 构建复合索引优化,索引尽量可以覆盖主要业务查询 sql避免索引失效 避免大…...
SQL 进阶刷题笔记
SQL 进阶刷题笔记 一、MySQL 进阶 这里主要是 MySQL 刷题相关笔记,方便后面温习和查阅,希望可以帮到大家!!! 题1 请计算每张SQL类别试卷发布后,当天5级以上的用户作答的人数uv和平均分avg_score࿰…...
[网鼎杯 2020 朱雀组]Think Java
SqlDict.java ,其中sql语句处存在sql注入漏洞 package .sqldict;import cn.abc.core.sqldict.Row; import cn.abc.core.sqldict.Table; import java...
AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL
目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告AIR32F103(二) Linux环境和LibOpenCM3项目模板AIR32F103(三) Linux环境基于标准外设库的项目模板AIR32F103(四) 27倍频216MHz,CoreMark跑分测试AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码AIR32F103(六) ADC,I2S…...
SpringBoot接口 - 如何统一异常处理
SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?为什么要优雅的处理异常如果我们不统一的处理异常,经常会在controller层有大量的异常…...
如何使用Python进行数据可视化
数据可视化是一种将数据呈现为图形或图表的技术,它有助于理解和发现数据中的模式和趋势。Python是一种流行的编程语言,有很多库可以帮助我们进行数据可视化。在本文中,我们将介绍使用Python进行数据可视化的基本步骤。 第一步:导…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
