深入探究Java中的对象类型变量声明操作——在声明对象时,系统究竟做了什么?

摘要:本文主要对Java中的对象类型变量的声明的底层原理做了探究。

​ 我们但凡是学过Java的,一定都知道Java中的对象类型变量的声明方式,那就是:类名 变量名 = new 类名()。不管这样说对不对,我们在这样写的时候,一定都是这样写的。比如我们写了一个Person类,在声明变量的时候,就要这样写:

Person liMing = new Person();

​ 我们并不会深入的去思考为什么这么写,这个语句中的主角是什么,这些问题我们都没有仔细去想过,因此在这里,我详细探讨这个问题,解决你心中的疑惑。

1.句柄

​ 在之前的学习中,我们实际上已经探究了句柄的原理,在这里我们再巩固一下。句柄就是我们常说的变量的变量名,一个变量是由变量名和值构成的,对于我们来说,变量的名字就是变量名,对于计算机来说,变量的变量名部分被称为句柄。我们在声明变量之后,变量就会在被声明的位置存储起来,如类的属性变量,就会被存储到位于堆内存中的对象实例中去,而方法中的变量,会在方法被调用的时候,运行到变量声明的地方在相应的栈空间上创建,变量被创建之后,虚拟机就可以根据句柄进行值的寻找了,当我们在变量创建之后调用变量,虚拟机就可以根据变量名来寻找句柄,并找到句柄后边的值进行取值,进而进行运算,正因如此,Java中的句柄和值是相邻的,而相对应的,在进行一个变量声明赋值的时候,等号左边的变量名就是句柄,右边的则是值。

​ 对于这个概念,我们在使用基本类型变量时非常好理解,对于基本类型变量的声明方式我们也很容易理解了,如下:

int a = 10;

​ 首先是声明类型为整形,句柄为a,这就引起了一个操作:先在栈空间上开辟了一个空间存放句柄,然后句柄的后边就是一块连续的32位大小的空间,这个空间就是变量a的值空间。而等号操作就会导致等号右边的值:10被放到值空间中。这样一个基本类型变量就声明好了,那么一个对象类型的变量是如何声明的呢?

2.对象类型变量的声明

​ 在对象类型变量的声明中,主角实际上是new,new关键字是这之中最为关键的东西。new是一个关键词,但是它实际上代表着一系列操作的执行,它属于一个操作开关,虚拟机一旦检测到new,就会执行一系列的操作。

Person liMing = new Person();

​ 在这个声明赋值之中,最前边的Person实际上是变量类型声明,它在整个操作的过程中,起到的作用是类型声明,但它实际上是new总体操作的一个参数,new会根据这个类型声明,使用路径定位的方式,寻找这个类,想要能创建这个类型的变量,就得让new能通过Person这个字符串,顺着路径能够找到它的类信息,我们如何让new通过路径找到它呢?实际上我们在Java中书写的import导入路径,就是在帮助new寻址,new的寻址能力并不特别行,它只能在当前程序所在的包下直接寻找,如果要是想寻找更多的东西,就要为程序加地址索引,也就是最上边的import,new会遍历它们并按照它们的路径寻找。

​ 当new寻找到相应的类信息后,就会检测这个类是否被初始化过,简而言之,就是检查这个类是否生成过对象,如果没有,就会对它进行forname()方法,这个方法是反射中的方法,使用这个方法可以获取这个类的所有信息,拥有类的所有信息之后,就可以通过它们来生成实例了。

​ 在初始化或者类被初始化过之后,就可以拿到类信息在堆空间中创建这个类的实例了,new会创建好这个实例,至此,对象实体的创建就完成了,然而对我们程序员来说,它没有真正的完成,因为它只是存在了,我们还没拿到它,因此new操作在最后会返回一个地址,这个地址通过等号的赋值功能被放在liMing句柄的后边,然而事情没那么简单,它还有一个操作。new的最后一个参数,便是神奇的构造器,在new后边书写,构造器会在new的所有操作完成前执行,构造器的作用并不是构造,构造是new的操作,我们更喜欢将构造器称之为init()方法,即初始化方法,在Java中也有类似的方法。构造器干的事情是在new返回地址之前对对象进行一些初始化操作,具体怎么初始化其实是我们自己定的,我们会在构造器中写自己想要进行的操作,比如给哪个属性赋值什么的,构造器就会在返回地址之前进行这些操作,在构造器完成之后,地址被返回给句柄,至此,我们就可以使用这个变量了。

3.重点

​ 构造器并不是构造对象的,new才是,构造器只是在初始化对象,最重要的操作是new关键字引起的操作,new实际上是一种简写机制,使用了封装思想,就是使用new关键字来代表一系列的操作执行,这个操作由虚拟机执行,我们只要写一个简单的new就行了,这是一种人性化的设计方式,最前边的类名是类型声明,也是一个参数,new中的操作会拿着这个参数进行类信息的寻找,如果找不到就会报错,在new内部还涉及了部分反射的知识,关于这里的研究我认为非常重要,以后还需继续深入学习。

​ 本文参考了两篇不错的博文,在此给出链接:

Java中new一个对象是一个怎样的过程?JVM中发生了什么? - 额是无名小卒儿 - 博客园 (cnblogs.com)

Java new关键字的对象内存分配原理 - naray - 博客园 (cnblogs.com)

深入探究Java中的对象类型变量声明操作——在声明对象时,系统究竟做了什么?的更多相关文章

  1. 初步探究java中程序退出、GC垃圾回收时,socket tcp连接的行为

    初步探究java中程序退出.GC垃圾回收时,socket tcp连接的行为 今天在项目开发中需要用到socket tcp连接相关(作为tcp客户端),在思考中发觉需要理清socket主动.被动关闭时发 ...

  2. 探究Java中的引用

    探究Java中的四种引用 从JDK1.2版本开始,Java把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用.本篇就来详细探究 ...

  3. java中,方法可以访问他的类对象的任何私有特性

    java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...

  4. Java从入门到精通——数据库篇之JAVA中的对Oracle数据库操作

    在Java中对Oracle数据库的操作分为两种:一.查询.二.非查询. 下面是我对其进行总结: 一.查询数据 /** * 根据用户代码查询 * @param userId * @return 如果存在 ...

  5. Java 中是如何支持正则表达式操作的?

    Java 中的 String 类提供了支持正则表达式操作的方法,包括:matches(). replaceAll().replaceFirst().split().此外,Java 中可以用 Patte ...

  6. 第69节:Java中数据库的多表操作

    第69节:Java中数据库的多表操作 前言 学习数据库的多表操作,去电商行业做项目吧!!! 达叔,理工男,简书作者&全栈工程师,感性理性兼备的写作者,个人独立开发者,我相信你也可以!阅读他的文 ...

  7. 探究Java中的锁

    一.锁的作用和比较 1.Lock接口及其类图 Lock接口:是Java提供的用来控制多个线程访问共享资源的方式. ReentrantLock:Lock的实现类,提供了可重入的加锁语义 ReadWrit ...

  8. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  9. 探究Java中Map类

    Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.       Map的接口       Map---实现Map       Map.Entry--Map的内部 ...

随机推荐

  1. Hyperf 接入阿里云ACM应用配置管理中心

    参考: 阿里云文档:https://help.aliyun.com/document_detail/85466.html?spm=a2c4g.11186623.6.550.43cb42d4Af4Tu0 ...

  2. 关于针对XSS漏洞攻击防范的一些思考

    众所周知,XSS几乎在最常见.危害最大的WEB漏洞.针对这个危害,我们应该怎么防范呢. 下面简单说一下思路. 作者:轻轻的烟雾(z281099678) 一.XSS漏洞是什么 XSS漏洞网上的资料太多, ...

  3. 24.-Django生成csv文件及下载

    一.csv文件定义 逗号分隔值(comma-separated values, csv,有时页称字符分隔值,因为分分隔字符页可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本) 说明:可被常见 ...

  4. CentOS 7.9 Related Software Directory

    一.CentOS 7.9 Related Software Directory Installing VMware Workstation Pro on Windows Installing Cent ...

  5. 「MySQL高级篇」MySQL索引原理,设计原则

    大家好,我是melo,一名大二后台练习生,大年初三,我又来充当反内卷第一人了!!! 专栏引言 MySQL,一个熟悉又陌生的名词,早在学习Javaweb的时候,我们就用到了MySQL数据库,在那个阶段, ...

  6. SpringBoot 阶段测试 1

    SpringBoot 阶段测试 1 目录 SpringBoot 阶段测试 1 1.使用JDK8新语法完成下列集合练习: 1.1 List中有1,2,3,4,5,6,7,8,9几个元素要求; (1) 将 ...

  7. Mysql+Mycat+NFS+Rsync+LVS+DNS+IPtables综合实验

    1.环境准备 服务器 IP地址 作用 系统版本 Mysql-master eth0:10.0.0.58 主数据库 Rocky8.6 Mysql-slave1 eth0:10.0.0.68 备数据库 R ...

  8. Codeforces Round #832 (Div. 2) A-D

    比赛链接 A 题解 知识点:贪心. 我们考虑把正数和负数分开放,显然把负数和正数放在一起的结果不会更优. 时间复杂度 \(O(n)\) 空间复杂度 \(O(1)\) 代码 #include <b ...

  9. 词向量word2vec(图学习参考资料)

    介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现. 项目链接: https://aistudio.baidu.com/aistudio/projectdetail/500940 ...

  10. 4.drf-版本管理

    根据RESTful规范,后端API中需要体现出版本,DRF中支持5种版本的设置,常见的三种如下 1. URL的GET中传递参数 在视图类中定义 from rest_framework.versioni ...