深入探究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. 初始Vue、Vue模板语法、数据绑定(2022/7/3)

    文章目录 1.Vue简介 1.1.Vue的安装使用 1.2.实际的运用案例 1.3.vue开发工具的使用(这个需要在浏览器中安装) 2.初始Vue 2.1 .基础知识 2.1 .代码实例 2.2 .页 ...

  2. 四、redis数据类型

    四.redis数据类型 redis可以理解成一个全局的大字典,key就是数据的唯一标识符.根据key对应的值不同,可以划分成5个基本数据类型. 1. string类型: 字符串类型,是 Redis 中 ...

  3. pod(七):静态pod

    目录 一.系统环境 二.前言 三.静态pod 3.1 何为静态pod 3.2 创建静态pod 3.2.1 使用--pod-manifest-path指定静态pod目录 3.2.2 静态pod默认目录/ ...

  4. JS逆向实战8——某网实战(基于golang-colly)

    其实本章算不上逆向教程 只是介绍golang的colly框架而已 列表页分析 根据关键字搜索 通过抓包分析可知 下一页所请求的参数如下 上图标红的代表所需参数 所以其实我们真正需要的也就是Search ...

  5. HTML躬行记(4)——Web音视频基础

    公司目前的业务会接触比较多的音视频,所以有必要了解一些基本概念. 文章涉及的一些源码已上传至 Github,可随意下载. 一.基础概念 本节音视频的基础概念摘自书籍<FFmpeg入门详解 音视频 ...

  6. 永久解决Ubuntu下adb权限问题

    在Linux环境下使用adb链接手机,经常会遇到全下问题,如下: adb: unable to connect for root: insufficient permissions for devic ...

  7. SpringBoot 01: JavaConfig + @ImportResource + @PropertyResource

    springboot的前置知识:通过注解创建对象和读取配置文件 1. JavaConfig 设计思想 使用java类作为xml配置文件的替代,是配置spring容器的纯java的方式 可以创建java ...

  8. 浅谈MYSQL的索引以及它的数据结构

    什么是索引 mysql的数据是持久化到磁盘的,写SQL查询数据也就是在磁盘的某个位置查找符合条件的数据,但是磁盘IO比起内存效率是极慢的,特别是数据量大的时候,这时候就需要引入索引来提高查询效率: 在 ...

  9. 2022春每日一题:Day 37

    题目:[USACO14FEB]Auto-complete S 字典树套路题,字典树优化剪枝,加个cnt标记即可 代码: #include <cstdio> #include <cst ...

  10. Go语言核心36讲05

    你已经使用过Go语言编写了小命令(或者说微型程序)吗? 当你在编写"Hello, world"的时候,一个源码文件就足够了,虽然这种小玩意儿没什么用,最多能给你一点点莫名的成就感. ...