面试官:在 Java 中 new 一个对象的流程是怎样的?彻底被问懵了。。(1)

简介: 面试官:在 Java 中 new 一个对象的流程是怎样的?彻底被问懵了。。

对象怎么创建,这个太熟悉了,new一下(其实还有很多途径,比如反射、反序列化、clone等,这里拿最简单的new来讲):


Dog dog = new Dog();

我们总是习惯于固定语句的执行,却对于背后的实现过程缺乏认知,而理解这个过程对后面晦涩难懂的反射和代理其实会有很大帮助,所以请务必学好这块内容。


在看这篇文章之前,啰嗦一句:如果你死记硬背下面所说的流程等于白看,就算现在记住了,一个礼拜后呢,一个月后你又能记得多少,因为对象创建过程这个知识点平常的工作中基本不会涉及到,太底层了,背熟的知识点不经常加以运用容易遗忘,所以我的建议是什么呢,流程做到心里大概有个数,其中涉及到关键的知识点记牢就可以了。


JVM内存

先简单说下java虚拟机内存模型和存放内容的区别,两部分:

栈内存 存放基本类型数据和对象的引用变量,数据可以直接拿来访问,速度比堆快

堆内存 存放创建的对象和数组,会由java虚拟机的自动垃圾回收来管理(GC),创建一个对象放入堆内的同时也会在栈中创建一个指向该对象堆内存中的地址引用变量,下面说的对象就是存在该内存中

下面我们就按照对象生成的过程来一一讲解参与其中过程的各个概念


首先有这么一个类,后面的初始化基于这个讲解:


/**
 * @author 炜哥
 * @since 2021-04-18 11:01:41
 *
 * 执行顺序:(优先级从高到低。)静态代码块>构造代码块>构造方法>普通方法。
 * 其中静态代码块只执行一次。构造代码块在每次创建对象是都会执行。
 */
public class Dog {
    //默认狗狗的最大年龄是16岁
    private static int dog_max_age = 16;
    //狗狗的名字
    private String dog_name;
    {
        System.out.println("狗狗的构造代码块");
    }
    static {
        System.out.println("狗狗的静态代码块");
    }
    //无参构造器故意没设
    //有参构造器
    public Dog(String dog_name) {
        this.dog_name = dog_name;
    }
    public void getDogInfo(){
        System.out.println("名字是:"+dog_name + "  年龄:" + dog_max_age);
    }
    //狗叫
    public static void barking(){
        System.out.println("汪汪汪~~~");
    }
}

JVM生成.class文件

一个java文件会在编译期间被初始化生成.class字节码文件,字节码文件是专门给JVM阅读的,我们平时吭哧吭哧写的一行行代码最终都会被编译成机器能看懂的语句,这个文件后面会被类加载器加载到内存。


image.png


类加载器加载.class文件

《深入理解Java的虚拟机》中大概有这么一句话:在虚拟机遇到一条new的指令时,会去检查一遍在静态常量池中能否定位到一个类的符号引用 (就这个类的路径+名字),并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果不是第一次使用,那必须先执行相应的类加载过程,这个过程由类加载器来完成。


类加载字面意思就可以理解成加载class文件,更准确点的说法就是会把class文件变成一个二进制流加载到内存中,即把类的描述信息加载到Metaspace,至于类加载器如何找到并把一个class文件转成IO流加载到内存中,我后面会专门写一篇关于类加载器的文章,这里就只要理解创建对象中有这么一步就行了。不过这里面有很重要的概念不得不讲:Class对象


知识扩展:Class对象

划重点,这是个非常重要的概念,理解它对于理解后面的反射和代理会有很大的帮助


类加载器 ClassLoader 加载class文件时,会把类里的一些数值常量、方法、类信息等加载到内存中,称之为类的元数据,最终目的是为了生成一个Class对象用来描述类,这个对象会被保存在.class文件里,可能有新手看到这里会比较懵逼,class也有对象?


当然了,Class是个实实在在的类(用来描述类的类,比较拗口),有构造方法( private ,意味着可以生成对象,但不能手动生成,由JVM自动创建Class对象),类加载器会给每个java文件都创建一个Class对象,用来描述类,我画个图:

image.png



//以下操作只能由jvm完成,我们手动做不了

Class cls1 = new Class(Dog.class.getClassLoader());

Class cls2 = new Class(Cat.class.getClassLoader());

Class cls3 = new Class(People.class.getClassLoader());


image.png



这个Class对象除了描述对应的类之外还有什么作用呢?也可以生成对象,就是java的反射概念(通过Class实例获取类信息) 上面说了,Class类是用来描述像People.Class类的类,那么它里面肯定包含了所有能够描述该class的所有属性,比如类名、方法、接口等,我们先到Class类源码中瞄一眼:


image.png


这里面有个方法 newInstance(),即创建对象, 我把源代码贴出来并简单解析下:


@CallerSensitive
public T newInstance()
    throws InstantiationException, IllegalAccessException
    {
        if (System.getSecurityManager() != null) {
            checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
        }
        if (cachedConstructor == null) {
            if (this == Class.class) {
                throw new IllegalAccessException(
                    "Can not call newInstance() on the Class for java.lang.Class"
                );
            }
            try {
                Class<?>[] empty = {};
                //声明无参构造对象
                final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
                // Disable accessibility checks on the constructor
                // since we have to do the security check here anyway
                // (the stack depth is wrong for the Constructor's
                // security check to work)
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = c;
            } catch (NoSuchMethodException e) {
             //如果class中没有无参构造方法,那么抛InstantiationException错误
                throw (InstantiationException)
                    new InstantiationException(getName()).initCause(e);
            }
        }
        Constructor<T> tmpConstructor = cachedConstructor;
        // Security check (same as in java.lang.reflect.Constructor)
        int modifiers = tmpConstructor.getModifiers();
        if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
            Class<?> caller = Reflection.getCallerClass();
            if (newInstanceCallerCache != caller) {
                Reflection.ensureMemberAccess(caller, this, null, modifiers);
                newInstanceCallerCache = caller;
            }
        }
        // Run constructor
        try {
         //最终还是调用了无参构造器对象的newInstance方法
            return tmpConstructor.newInstance((Object[])null);
        } catch (InvocationTargetException e) {
            Unsafe.getUnsafe().throwException(e.getTargetException());
            // Not reached
            return null;
        }
    }
相关文章
|
2月前
|
前端开发 Java API
2025 年 Java 全栈从环境搭建到项目上线实操全流程指南:Java 全栈最新实操指南(2025 版)
本指南涵盖2025年Java全栈开发核心技术,从JDK 21环境搭建、Spring Boot 3.3实战、React前端集成到Docker容器化部署,结合最新特性与实操流程,助力构建高效企业级应用。
535 1
|
2月前
|
消息中间件 Java Kafka
Java 事件驱动架构设计实战与 Kafka 生态系统组件实操全流程指南
本指南详解Java事件驱动架构与Kafka生态实操,涵盖环境搭建、事件模型定义、生产者与消费者实现、事件测试及高级特性,助你快速构建高可扩展分布式系统。
169 7
|
2月前
|
消息中间件 Java 数据库
Java 基于 DDD 分层架构实战从基础到精通最新实操全流程指南
本文详解基于Java的领域驱动设计(DDD)分层架构实战,结合Spring Boot 3.x、Spring Data JPA 3.x等最新技术栈,通过电商订单系统案例展示如何构建清晰、可维护的微服务架构。内容涵盖项目结构设计、各层实现细节及关键技术点,助力开发者掌握DDD在复杂业务系统中的应用。
345 0
|
4月前
|
缓存 Java 关系型数据库
2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
203 2
|
4月前
|
自然语言处理 前端开发 Java
JBoltAI 框架完整实操案例 在 Java 生态中快速构建大模型应用全流程实战指南
本案例基于JBoltAI框架,展示如何快速构建Java生态中的大模型应用——智能客服系统。系统面向电商平台,具备自动回答常见问题、意图识别、多轮对话理解及复杂问题转接人工等功能。采用Spring Boot+JBoltAI架构,集成向量数据库与大模型(如文心一言或通义千问)。内容涵盖需求分析、环境搭建、代码实现(知识库管理、核心服务、REST API)、前端界面开发及部署测试全流程,助你高效掌握大模型应用开发。
412 5
|
3月前
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
336 0
|
2月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
339 63
|
2月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
147 3
|
3月前
|
人工智能 Cloud Native Java
Java 技术栈企业级应用开发全流程
本指南通过构建企业级电商系统,全面解析现代化Java技术栈实战应用。涵盖Spring Boot 3、微服务架构、云原生部署、服务治理、监控可观测性及AI集成,助开发者掌握全流程开发技能,打造高效可扩展的企业级应用。
206 0
Java 技术栈企业级应用开发全流程
|
3月前
|
安全 Java 数据库
使用Java实现用户的注册和登录流程
以上提供了用户注册和登录的基本框架和必要的说明。在具体的应用场景中,可能还需结合框架特性如Spring Security等提供的高级特性来实现更为完备和安全的用户认证机制。在开发期间,务必注重代码的安全性、清晰性和可维护性,为用户资料保驾护航。
186 13

热门文章

最新文章