Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化

这篇具有很好参考价值的文章主要介绍了Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引出


1.类什么时候被加载到JVM中,new,Class.forName: Class.forName(“包名.类名”);
2.创建对象的方式,反射,本质是获得类的类对象Class;
3.克隆clone,深拷贝,浅拷贝的对比;
4.序列化和反序列化的方式;

类什么时候被加载JVM中

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,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对象

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言
Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

如何获取Class对象【反射的基础】

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

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

案例:连接数据库方法

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

类加载采用了反射的方式

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

采用枚举方式封装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

  • 继承的时候,可以将子类的访问控制符扩大,但不能缩小;子类不得比父类抛出更多,更大的异常。
  • 浅拷贝、深拷贝问题:

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

浅拷贝

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

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

深拷贝

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

    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:代表本包或者继承
    // 继承的时候,可以将子类的访问控制符扩大,但不能缩小;
    // 子类不能比父类抛出更多的异常
    @Override
    public 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;
    }
}

进行测试

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

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—->对象写入文件

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

serialVersionUID :在序列化的时候指定的编号, 在反序列化时应该保证版本号一致。

Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化,Java,java,jvm,开发语言

案例:把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.序列化和反序列化的方式;文章来源地址https://www.toymoban.com/news/detail-657112.html

到了这里,关于Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • JVM运行时区域——对象创建内存分配过程

    JVM运行时区域——对象创建内存分配过程

            新创建的对象 , 都存放在伊甸园区域 ,当垃圾回收时,将伊甸园区域的垃圾数据销毁,然后将存活的对象转移到幸存者0区域,之后创建的新的对象还是存放在伊甸园区域,等到再次垃圾回收后,将伊甸园区域和幸存者0区域中存活的对象一起转移到幸存者1区域中

    2024年02月15日
    浏览(12)
  • JVM面试题-JVM对象的创建过程、内存分配、内存布局、访问定位等问题详解

    JVM面试题-JVM对象的创建过程、内存分配、内存布局、访问定位等问题详解

    内存分配的两种方式 指针碰撞 适用场合:堆内存 规整 (即没有内存碎片)的情况下。 原理:用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没用过的内存方向将该指针移动对象内存大小位置即可。 使用该分配方式的GC收集器:

    2024年02月08日
    浏览(10)
  • [JVM] Java类的加载过程

    [JVM] Java类的加载过程

    在Java中,类的加载是指在程序运行时将类的二进制数据加载到内存中,并转化为可以被JVM执行的形式的过程。类的加载过程主要包括以下几个步骤: 加载 (Loading):通过类的全限定名,使用类加载器将类的二进制数据加载到JVM中。类加载器会根据类的名称找到对应的字节码

    2024年01月16日
    浏览(8)
  • 【Java】JVM执行流程、类加载过程和垃圾回收机制

    【Java】JVM执行流程、类加载过程和垃圾回收机制

    JVM,就是Java虚拟机,Java的的程序都是运行在JVM当中。 程序在执行之前先要把java源代码转换成字节码(class文件),JVM 首先需要把字节码通过一定的方(类加载器(ClassLoader)) 把文件加载到内存中的运行时数据区(Runtime Data Area) ,而字节码文件是 JVM 的一套指令集规范,并

    2024年02月16日
    浏览(12)
  • 【Mybatis源码】XMLConfigBuilder构建器 - 加载XML与创建Configuration对象的过程

    XMLConfigBuilder是Mybatis中定义的进行构建Configuration对象的类,此类用于读取XML配置文件创建并初始化Configuration对象;本篇我们主要介绍加载XML文件与创建Configuration对象的过程。 下面是从Configuration类中取到的代码片段:

    2024年02月08日
    浏览(11)
  • 深入JVM了解Java对象实例化过程

    深入JVM了解Java对象实例化过程

    new :最常见的方式、 Xxx 的静态方法, XxxBuilder/XxxFactory 的静态方法 Class的newInstance 方法:反射的方式,只能调用空参的构造器,权限必须是public Constructor的newInstance(XXX) :反射的方式,可以调用空参、带参的构造器,权限没有要求 使用 clone() :不调用任何的构造器,要求当

    2023年04月24日
    浏览(8)
  • 深入理解Java虚拟机jvm-对象的内存布局

    深入理解Java虚拟机jvm-对象的内存布局

    在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例 数据(Instance Data)和对齐填充(Padding)。 HotSpot虚拟机对象的对象头部分包括两类信息。第一类是用于存储对象自身的运行时数据,如哈 希码(HashCode)、GC分代年龄、锁状态标志、

    2024年02月09日
    浏览(7)
  • 【JVM】Java堆 :深入理解内存中的对象世界

    【JVM】Java堆 :深入理解内存中的对象世界

    人不走空                                                                            目录         🌈个人主页:人不走空       💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 ​编辑 什么是Java堆? 作用和特点 1. 存储对象实例 2. 垃圾收集 3. 对象

    2024年01月19日
    浏览(12)
  • 【JVM】详细解析java创建对象的具体流程

    【JVM】详细解析java创建对象的具体流程

    目录 一、java创建对象的几种方式 1.1、使用new  1.2、反射创建对象 1.2.1、Class.newInstance创建对象 1.2.2、调用构造器再去创建对象Constructor.newInstance  1.3、clone实现 1.4、反序列化 二、创建对象的过程 2.1、分配空间的方式 1、指针碰撞 2、空闲列表 3、怎么选择分配方式 三、

    2024年02月15日
    浏览(7)
  • java对象创建的过程

    java对象创建的过程

    2024年02月11日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包