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对象【反射的基础】

  1. 对象.getClass()
  2. 类.class
  3. Class.forName(“包名.类名”)

在这里插入图片描述

案例:连接数据库方法

在这里插入图片描述

类加载采用了反射的方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6IBnBmB-1683902514958)(D:\javalearn\思维导图笔记\mdPictures\image-20230512204643739.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)]

案例:把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.序列化和反序列化的方式;

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

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

相关文章

【面试题】前端面试复习6---性能优化

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 性能优化 一、性能指标 要在 Chrome 中查看性能指标&#xff0c;可以按照以下步骤操作&#xff1a; 打开 Chrome 浏览器&#xff0c;并访问你想要测试…

lvs-DR

lvs-DR数据包流向分析 client向目标VIP发出请求。 DIR根据负载均衡算法一台active的RS&#xff08;RIR1&#xff09;&#xff0c;将RIP1所在的网卡的mac地址作为目标的mac地址&#xff0c;发送到局域网里。 RIRI在局域网中的收到这个帧&#xff0c;拆开后发现目标&#xff08…

IPEmotion交流电功率分析计算

一 应用背景 随着国内电动汽车行业的快速发展&#xff0c;在相同的道路环境和行驶状态下&#xff0c;增加电动车的整体续航里程和提升乘员对于行驶途中用电需求的满意度尤为重要。对此&#xff0c;需要采集试验过程中交直流电压电流信号&#xff0c;以计算出车辆各种部件输出和…

Docker容器与虚拟化技术:Docker镜像创建、Dockerfile实例

目录 一、理论 1.Docker镜像的创建方法 2.Docker镜像结构的分层 3.Dockerfile 案例 4.构建Systemctl镜像&#xff08;基于SSH镜像&#xff09; 5.构建Tomcat 镜像 6.构建Mysql镜像 二、实验 1.Docker镜像的创建 2. Dockerfile 案例 3.构建Systemctl镜像&#xff08;…

大数据平台需要做等保测评吗?怎么做?

大数据时代的数据获取方式、存储规模、访问特点、关注重点都有了很大不同&#xff0c;所以保证大数据平台数据安全尤其重要。因此不少人在问&#xff0c;大数据平台需要做等保测评吗&#xff1f;怎么做&#xff1f; 大数据平台需要做等保测评吗&#xff1f; 大数据平台是需要做…

数据结构之——(手撕)顺序表

本章会介绍的知识点如下图&#xff1a; 1&#xff1a; 顺序表的概念&#xff1a;顺序表是用一段物理地址连续的存储单元依次存储数据的线性结构&#xff0c;通常我们使用数组来表示&#xff0c;对数组进行增删查改。 顺序表的结构&#xff1a;逻辑结构与物理结构都是内存中一块…

AI Agent在情景猜谜场景下的AgentBench基准测试

目录 AgentBench评估哪些场景? 近日,来自清华大学、俄亥俄州立大学和加州大学伯克利分校的研究者设计了一个测试工具——AgentBench,用于评估LLM在多维度开放式生成环境中的推理能力和决策能力。研究者对25个LLM进行了全面评估,包括基于API的商业模型和开源模型。 他们发现…

docker之Consul环境的部署

目录 一.Docker consul的介绍 1.1template模板(更新) 1.2registrator&#xff08;自动发现&#xff09; 1.3agent(代理) 二.consul的工作原理 三.Consul的特性 四.Consul的使用场景 五.搭建Consul的集群 5.1需求 5.2部署consul 5.3主服务器[192.168.40.20] 5.4client部署&…

python实战【外星人入侵】游戏并改编为【梅西vsC罗】(球迷整活)——搭建环境、源码、读取最高分及生成可执行的.exe文件

文章目录 &#x1f3a5;前言&#x1f4bc;安装Pygame&#x1f50b;游戏的实现读写并存储【外星人入侵】游戏最高分游戏源码alien_invasion.pygame_functions.pyship.pyalien.pybullet.pybutton.pyscoreboard.pygame_stats.pysettings.py宇宙飞船和外星人的 .bmp类型文件 &#…

Spark 图计算ONEID 进阶版

0、环境信息 本文采用阿里云maxcompute的spark环境为基础进行的&#xff0c;搭建本地spark环境参考搭建Windows开发环境_云原生大数据计算服务 MaxCompute-阿里云帮助中心 版本spark 2.4.5&#xff0c;maven版本大于3.8.4 ①配置pom依赖 详见2-1 ②添加运行jar包 ③添加配置信…

JVM——JVM 垃圾回收

文章目录 写在前面本节常见面试题本文导火索 1 揭开 JVM 内存分配与回收的神秘面纱1.1 对象优先在 eden 区分配1.2 大对象直接进入老年代1.3 长期存活的对象将进入老年代1.4 动态对象年龄判定1.5 主要进行 gc 的区域 2 对象已经死亡&#xff1f;2.1 引用计数法2.2 可达性分析算…

java面试基础 -- 深克隆 浅克隆

引例 说到java的克隆你还记得多少? 一说到克隆你可能就会想起来那个接口, 没错, 他就是Cloneable Cloneable是java里面内置的很常用的接口, 我们说 Object类中也有一个clone方法: 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedEx…

如何下载和安装google字体(中文)

打开&#xff1a;https://fonts.google.com/ 点击字体 下载 解压 双击安装 查看 控制面板-》字体-》

武汉凯迪正大—变比组别测试仪

一、概述 在电力变压器的半成品、成品生产过程中&#xff0c;新安装的变压器投入运行之前以及根据国家电力部的预防性试验规程中&#xff0c;要求变压器进行匝数比或电压比测试。传统的变比电桥操作繁琐&#xff0c;读数不直观&#xff0c;且要进行必要的换算&#xff0c;测试时…

git拉取失败/git fatal终极解决方法

前言 被折磨不下20次总结出来的终极方案 步骤 0 首先关闭代理试试&#xff0c;不行就下一步 1 重置代理或者取消代理的方式 git config --global --unset http.proxy git config --global --unset https.proxy添加全局代理 git config --global http.proxy git config …

Docker容器:Docker-Compose

Docker容器&#xff1a;Docker-Compose 一.Docker-Compose概念 1.Docker-Compose使用场景 一个Dockerfile模板文件可以定义一个单独的应用容器&#xff0c;如果需要定义多个容器就需要服务编排。服务编排有很多种技术方案&#xff0c;今天是介绍 Docker 官方产品 Docker Com…

【React】生命周期和钩子函数

概念 组件从被创建到挂载到页面中运行&#xff0c;再到组件不用时卸载的过程。 只有类组件才有生命周期。 分为三个阶段&#xff1a; 挂载阶段更新阶段销毁阶段 三个阶段 挂载阶段 钩子函数 - constructor 创建阶段触发 作用&#xff1a;创建数据 之前定义状态是简写&…

面试题-React(三):什么是JSX?它与常规JavaScript有什么不同?

在React的世界中&#xff0c;JSX是一项引人注目的技术&#xff0c;它允许开发者在JavaScript中嵌套类似HTML的标签&#xff0c;用于描述UI组件的结构。本篇博客将通过丰富的代码示例&#xff0c;深入探索JSX语法&#xff0c;解析其在React中的用法和优势。 一、JSX基础语法 在…

PHP服饰文化网站系统Dreamweaver开发mysql数据库web结构php编程计算机网页项目

一、源码特点 PHP 服饰文化网站系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 源码下载 https://download.csdn.net/download/qq_41221322/88236778 PHP服饰文化网站…

两两交换链表中的节点

你存在&#xff0c;我深深的脑海里~ 题目&#xff1a; 示例&#xff1a; 思路&#xff1a; 这个题有点类似于反转一个单链表&#xff0c;不同的地方在于这个题不全反转&#xff0c;所以我们不同的地方在于此题多用了一个prve指针保存n1的前一个节点&#xff0c;以及头的改变&a…