Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化
目录
- 引出
- 类什么时候被加载JVM中
- 创建对象几种方式
- 1.new 看到new : new Book()
- 2.反射 Class.forName(“包名.类名”)
- 如何获取Class对象【反射的基础】
- 案例:连接数据库方法
- 3.克隆(拷贝)clone
- 浅拷贝
- 深拷贝
- 案例
- 序列化和反序列化
- 对象流-把对象存储为dat文件
- 总结
引出
1.类什么时候被加载到JVM中,new,Class.forName: Class.forName(“包名.类名”);
2.创建对象的方式,反射,本质是获得类的类对象Class;
3.克隆clone,深拷贝,浅拷贝的对比;
4.序列化和反序列化的方式;
类什么时候被加载JVM中

Hello h; // 此时没有用Hello,jvm并没有进行类加载
- 看到new : new Book()
- Class.forName: Class.forName(“包名.类名”)
- 类加载器
package com.tianju.auth.reflect;public class HelloTest1 {public static void main(String[] args) throws ClassNotFoundException {Hello h; // 此时没有用Hello,jvm并没有进行类加载System.out.println("**********");new Hello(); // new 的时候会加载到内存中System.out.println("**********");Class.forName("com.tianju.auth.reflect.Hello");}
}
package com.tianju.auth.reflect;public class Hello {static {System.out.println("hello");}public Integer count(Integer a,Integer b){return a+b;}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {int a = 3;Class<?> aClass = Hello.class; // ?泛型的写法Class<?> aClass1 = Class.forName("com.tianju.auth.reflect.Hello");Class<? extends Hello> aClass2 = new Hello().getClass();System.out.println(aClass);System.out.println(aClass1);System.out.println(aClass2);Hello o = (Hello) aClass.newInstance();int count = o.count(1, 2);System.out.println(count);}
}
创建对象几种方式
1.new 看到new : new Book()
2.反射 Class.forName(“包名.类名”)
一个类会产生一个唯一的Class对象,JVM底层原理
Car.java 编译成 Car.clase 类加载到 JVM 中,加载时还没有创建对象;
进入JVM中给类Car创建单独的唯一的对象Class 类,该Class对象中存储了Car类的一些必要信息,没有记录相关的值;
以Class对象生产成多个Car对象,通过Class类映射出多个Car对象


如何获取Class对象【反射的基础】
- 对象.getClass()
- 类.class
- Class.forName(“包名.类名”)

案例:连接数据库方法

类加载采用了反射的方式
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6IBnBmB-1683902514958)(D:\javalearn\思维导图笔记\mdPictures\image-20230512204643739.png)]](https://img-blog.csdnimg.cn/bf0e382a7536417db3022fe9f2def658.png)
采用枚举方式封装JDBC单例
方法程序:
package com.tianju.util;import java.sql.*;
import java.util.Objects;/*** 采用枚举单例封装数据库*/
public enum DbUtilEnum {INSTANCE;private Connection conn;private PreparedStatement pst;private ResultSet rs;private DbUtilEnum() {// 注册驱动-类加载register();}/*** 第一步:注册驱动,类加载*/private void register(){try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}// 建立数据库连接// 192.168.0.134:3306// root,123/*** 第二步:建立数据库连接* @param ipAdress ip地址+端口号* @param user 用户名root* @param password 密码123*/public void connect(String ipAdress,String user,String password){String url = "jdbc:mysql://"+ipAdress+"/emp_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";try {conn = DriverManager.getConnection(url,user,password);System.out.println("成功连接数据库:"+ipAdress);} catch (SQLException e) {throw new RuntimeException(e);}}/*** 第三步:准备SQL语句,* @param sql sql语句*/public void setPreparedStatement(String sql, Object...values){try {pst = conn.prepareStatement(sql);// 逐个填充 ? 处的空缺for (int i=0;i<values.length;i++){pst.setObject(i+1, values[i]);}} catch (SQLException e) {throw new RuntimeException(e);}}/*** 第四步:增加,删除,修改*/public void executeUpdate(){try {pst.executeUpdate();System.out.println("执行增删改操作");} catch (SQLException e) {throw new RuntimeException(e);}}/*** 第四步:查询ResultSet,调用next()方法* @return 返回查询的ResultSet*/public ResultSet executeQuery(){try {rs = pst.executeQuery();System.out.println("执行查询操作,返回结果");return rs;} catch (SQLException e) {throw new RuntimeException(e);}}/*** 第五步:关闭连接*/public void close(){try {if (Objects.nonNull(rs)){rs.close();}if (Objects.nonNull(pst)){pst.close();}if (Objects.nonNull(conn)){conn.close();}System.out.println("操作完成,关闭数据库连接");} catch (SQLException e) {throw new RuntimeException(e);}}
}
3.克隆(拷贝)clone
- 继承的时候,可以将子类的访问控制符扩大,但不能缩小;子类不得比父类抛出更多,更大的异常。
- 浅拷贝、深拷贝问题:

浅拷贝

// protected:代表本包或者继承// 继承的时候,可以将子类的访问控制符扩大,但不能缩小;// 子类不能比父类抛出更多的异常@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}
深拷贝

public Book deepClone(){Book book = new Book();Author au = new Author();au.setName(author.getName());book.setAuthor(au);book.setTitle(this.title);book.setPrice(this.price);return book;}
案例
Author.java实体类
package com.tianju.auth.reflect;import lombok.Data;@Data
public class Author {private String name;
}
Book.java实体类
implements Cloneable{ // 可以克隆的
package com.tianju.auth.reflect;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Cloneable{ // 可以克隆的private String title;private Author author;public double price;static {System.out.println("book的静态代码块");}// protected:代表本包或者继承// 继承的时候,可以将子类的访问控制符扩大,但不能缩小;// 子类不能比父类抛出更多的异常@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}public Book deepClone(){Book book = new Book();Author au = new Author();au.setName(author.getName());book.setAuthor(au);book.setTitle(this.title);book.setPrice(this.price);return book;}
}
进行测试

package com.tianju.auth.reflect;public class TestDemo{public static void main(String[] args) throws CloneNotSupportedException {Author author = new Author();author.setName("吴承恩");Book book = new Book("三国演义", author,12.56);Book book1 = book;System.out.println(book1==book);// == 两个引用是否指向同一个对象// clone创建了一个新的对象,只是值一样Book bookClone = (Book) book.clone();// 深拷贝,创建了新的对象,上面的浅拷贝,只是拷贝了引用Book deepClone = book.deepClone();System.out.println(bookClone==book);System.out.println("克隆前:"+book);System.out.println("克隆后:"+bookClone);author.setName("小柯基");System.out.println("修改后的原对象:"+book);System.out.println("修改后的clone对象:"+bookClone);// 深拷贝System.out.println("***********");System.out.println("深拷贝的方法:"+deepClone);}
}
序列化和反序列化
对象流-把对象存储为dat文件
要点:
(1)实体类需要实现序列化接口 public class Car implements Serializable;【标记接口】
(2)序列化的版本号最好不要写,交给JVM实现,要保证版本号一致;
功能:
ObjectOutputStream—->对象写入文件



serialVersionUID :在序列化的时候指定的编号, 在反序列化时应该保证版本号一致。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ae2rqAoS-1683890070789)(D:\javalearn\思维导图笔记\mdPictures\image-20230508094242209.png)]](https://img-blog.csdnimg.cn/54d6d4f3c5a54b32a310ff68771df373.png)
案例:把car类存储到dat文件中
1)类需要实现序列化的接口
public class Car implements Serializable { // 需要实现序列化的接口// 序列化的版本号,不要写,交给jvm实现;保证读的和写的对象实体类要一样
// private static final long serialVersionUID = 2L;private Integer id;private String name;public Car() {}
}
2)从内存写入硬盘文件,为out,用write
ObjectOutputStream out =new ObjectOutputStream(new FileOutputStream("D:\\Myprogram\\idea-workspace\\IOStrem\\IOStrem\\src\\com\\woniuxy\\resources\\car.dat"));
// 存多个的解决方法,存到List中
List<Car> list = new ArrayList<>();
list.add(new Car(1, "BMW"));
list.add(new Car(2, "BYD"));
list.add(new Car(3, "BMW"));
out.writeObject(list); // list也实现了Serializable
out.flush();
out.close();
3)从硬盘读入内存,为in,用read
ObjectInputStream in =new ObjectInputStream(new FileInputStream("D:\\Myprogram\\idea-workspace\\IOStrem\\IOStrem\\src\\com\\woniuxy\\resources\\car.dat")
);
// Car car = (Car) in.readObject(); // 读对象,向下转型
// System.out.println(car);
List<Car> list = (List<Car>) in.readObject();
System.out.println(list);
list.forEach(car -> System.out.println(car)); // list的lamda表达式
list.forEach(System.out::println); // 上面的简化写法
in.close(); // 记得关闭
总结
1.类什么时候被加载到JVM中,new,Class.forName: Class.forName(“包名.类名”);
2.创建对象的方式,反射,本质是获得类的类对象Class;
3.克隆clone,深拷贝,浅拷贝的对比;
4.序列化和反序列化的方式;
相关文章:
Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化
目录 引出类什么时候被加载JVM中创建对象几种方式1.new 看到new : new Book()2.反射 Class.forName(“包名.类名”)如何获取Class对象【反射的基础】案例:连接数据库方法 3.克隆(拷贝)clone浅拷贝深拷贝案例 序列化和反序列化对象流-把对象存…...
扩散模型实战(四):从零构建扩散模型
推荐阅读列表: 扩散模型实战(一):基本原理介绍 扩散模型实战(二):扩散模型的发展 扩散模型实战(三):扩散模型的应用 本文以MNIST数据集为例,从…...
YOLOv5、YOLOv8改进:S2注意力机制
目录 1.简介 2.YOLOv5改进 2.1增加以下S2-MLPv2.yaml文件 2.2common.py配置 2.3yolo.py配置 1.简介 S2-MLPv2注意力机制 最近,出现了基于 MLP 的视觉主干。与 CNN 和视觉Transformer相比,基于 MLP 的视觉架构具有较少的归纳偏差,在图像识…...
LeetCode 542. 01 Matrix【多源BFS】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
使用open cv进行角度测量
使用open cv进行角度测量 用了一点初中数学的知识,准确度,跟鼠标点的准不准有关系,话不多说直接上代码 import cv2 import mathpath "test.jpg" img cv2.imread(path) pointsList []def mousePoint(event, x, y, flags, param…...
java 线程池实现多线程处理list数据
newFixedThreadPool线程池实现多线程 List<PackageAgreementEntity> entityList new CopyOnWriteArrayList<>();//多线程 10个线程//int threadNum 10;int listSize 300;List<List<PackageAgreementDto>> splitData Lists.partition(packageAgre…...
Centos安装Docker
Centos安装 Docker 从 2017 年 3 月开始 docker 在原来的基础上分为两个分支版本: Docker CE 和 Docker EE。 Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需付费使用。 本文介绍 Docker CE 的安装使用。 移除旧的版本&#x…...
Unity启动项目无反应的解决
文章首发见博客:https://mwhls.top/4803.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议,私信不回。 摘要:通过退还并重新载入许可证以解决Unity项目启动无反应问题。 场景 Unity Hub启动项目…...
2.3 opensbi: riscv: opensbi源码解析
文章目录 3. sbi_init()函数4. init_coldboot()函数4.1 sbi_scratch_init()函数4.2 sbi_domain_init()函数4.3 sbi_scratch_alloc_offset()函数4.4 sbi_hsm_init()函数4.5 sbi_platform_early_init()函数3. sbi_init()函数 函数位置:lib/sbi/sbi_init.c函数参数:scratch为每个…...
点破ResNet残差网络的精髓
卷积神经网络在实际训练过程中,不可避免会遇到一个问题:随着网络层数的增加,模型会发生退化。 换句话说,并不是网络层数越多越好,为什么会这样? 不是说网络越深,提取的特征越多ÿ…...
Ubuntu服务器service版本初始化
下载 下载路径 官网:https://cn.ubuntu.com/ 下载路径:https://cn.ubuntu.com/download 服务器:https://cn.ubuntu.com/download/server/step1 点击下载(22.04.3):https://cn.ubuntu.com/download/server…...
re学习(33)攻防世界-secret-galaxy-300(脑洞题)
下载压缩包: 下载链接:https://adworld.xctf.org.cn/challenges/list 参考文章:攻防世界逆向高手题之secret-galaxy-300_沐一 林的博客-CSDN博客 发现这只是三个同一类型文件的三个不同版本而已,一个windows32位exe࿰…...
Mybatis Plus中使用LambdaQueryWrapper进行分页以及模糊查询对比传统XML方式进行分页
传统的XML分页以及模糊查询操作 传统的XML方式只能使用limit以及offset进行分页,通过判断name和bindState是否为空,不为空则拼接条件。 List<SanitationCompanyStaff> getSanitationStaffInfo(Param("name") String name,Param("bi…...
vue中push和resolve的区别
import { useRouter } from vue-router;const routeuseRouter()route.push({path:/test,query:{name:1}})import { useRouter } from vue-router;const routeuseRouter()const urlroute.resolve({path:/test,query:{name:1}})window.open(url.href)比较上述代码会发现,resolve能…...
详解RFC 3550文档-1
1. 介绍 rfc 3550描述了实时传输协议RTP。RTP提供端到端的网络传输功能,适用于通过组播或单播网络服务传输实时数据(如音频、视频或仿真数据)的应用。 TP本身不提供任何机制来确保及时交付或提供其他服务质量保证,而是依赖于较低层的服务来完成这些工作。它不保证传输或防止…...
Go 与 Rust
目录 1. Go 与 Rust 1. Go 与 Rust 一位挺 Rust 的网友说道: “我也为这个选择烦恼了很久。最终 Rust 胜出了。首先, 我感觉 Rust 更接近于以前 Pascal 时代的东西, 你可以控制一切; 其次, 如果 wasm 和相关技术大爆发, Rust 将是一个更安全的选择; 然后, 我们已经有了 Python…...
Android Studio实现读取本地相册文件并展示
目录 原文链接效果 代码activity_main.xmlMainActivity 原文链接 效果 代码 activity_main.xml 需要有一个按钮和image来展示图片 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk…...
python的全局解释锁(GIL)
一、介绍 全局解释锁(Global Interpreter Lock,GIL)是在某些编程语言的解释器中使用的一种机制。在Python中,GIL是为了保证解释器线程安全而引入的。 GIL的作用是在解释器的执行过程中,确保同一时间只有一个线程可以…...
小程序swiper一个轮播显示一个半内容且实现无缝滚动
效果图: wxml(无缝滚动:circular"true"): <!--components/tool_version/tool_version.wxml--> <view class"tool-version"><swiper class"tool-version-swiper" circul…...
【自然语言处理】关系抽取 —— SimpleRE 讲解
SimpleRE 论文信息 标题:An Embarrassingly Simple Model for Dialogue Relation Extraction 作者:Fuzhao Xue 期刊:ICASSP 2022 发布时间与更新时间:2020.12.27 2022.01.25 主题:自然语言处理、关系抽取、对话场景、BERT arXiv:[2012.13873] An Embarrassingly Simple M…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
