深入探究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. 记录一次成功反混淆脱壳及抓包激活app全过程

    记录一次成功反混淆脱壳及抓包激活app全过程 前言 ​ 近期接到一个需求,要对公司之前开发的一款app进行脱壳.因为该app是两年前开发的,源代码文件已经丢失,只有加壳后的apk文件,近期要查看其中一 ...

  2. [WPF] 抄抄超强的苹果官网滚动文字特效实现

    1. 前言 今天 ChokCoco 大佬发布了一篇博客 超强的苹果官网滚动文字特效实现,iPhone 我是买不起的,但不妨碍我对抄特效感兴趣,正好我这周安排的工作已经完成了,于是有空练练手实现了一个 ...

  3. 前端性能优化——首屏时间&&白屏时间

    1.首屏时间概念 首屏时间是指用户打开一个网站时,直到浏览器首页面内容渲染完成的时间. 2.白屏时间概念 白屏时间即是,浏览器开始显示内容的时间,所以我们一般认为解析完<head>的时刻, ...

  4. 题解 P6355 [COCI2007-2008#3] DEJAVU

    kcm的原题.. 貌似是个组合数(? \(\sf {Solution}\) 对于每一个点,我们需要统计与它同一行的点数\(a\) 和同一列的点数\(b\) ,则该点对结果\(ans\) 的贡献为\(( ...

  5. Kafka 架构和原理机制 (图文全面详解)

    目录 一:Kafka 简介 二:Kafka 基本架构 三:Kafka 基本原理 四:Zookeeper 在 kafka 的作用 五:Kafka 的特性 六:Kafka 的应用场景 一:Kafka 简介 ...

  6. 优雅的写好Vue项目代码 — 路由拆分、Vuex模块拆分、element按需加载

    目录 路由的拆分 VUEX模块拆分 Element UI库按需加载的优雅写法 路由的拆分 项目较大路由较多时,路由拆分是一个不错的代码优化方案,按不同业务分为多个模块,结构清晰便于统一管理. requ ...

  7. vs 自定义代码块

    代码自动生成,让代码飞~ 我目前用的是vs2013,c,c++用的多,vs自带了一套代码块规则,下面我们就以for举例子. 1 原生代码块怎么使用 输入for后按Tab键: 这时候可以修改 size_ ...

  8. JavaScript&Bootstrap

    1. JS介绍 JS诞生主要是完成页面的数据验证.因此它运行在客户端,需要浏览器来执行JS代码 JS最早取名LiveScript:为了吸引更多的Java程序员,更名JavaScript JS是弱类型, ...

  9. C#使用附加到进程调试

    微软官网的调试进程介绍 首先运行bin下的可执行文件,然后打开源代码,选择调试--->附加到进程.

  10. 【Docker】容器使用规范--安全挂载建议

    容器挂载过程和安全挂载建议 绑定挂载 本文所提到的挂载主要指绑定挂载(bind mount),即通过-v /xx/xx:/xx/xx 和 --mount type=bind,xxx,xxx两种方式设置 ...