一个对象从无到有的过程

A a = new A()

1、JVM遇到new指令就会去堆内存分配一块内存空间,内存的大小在编译期间就可以确定

2、接着调用A的构造函数,这里构造的时候会沿着继承树逆流而上,一直到Object。

  先看一段代码:

 package jvm.test3;

 public class Sup {

     public int a;
public String b; Sup(int a, String b){
System.out.println("Sup constructor!!!");
System.out.println(this.getClass().getName());
this.a = a;
this.b = b;
this.printMsg();
} private void printMsg(){
System.out.println("Sup: " + "a=" + a + " b=" + b);
}
} package jvm.test3; public class Sub extends Sup{ Sub(int a, String b) {
super(a, b);
System.out.println("Sub constructor!!!");
} } package jvm.test3; public class Test { public static void main(String[] args) {
new Sub(11,"hello");
} }

输出:

Sup constructor!!!
jvm.test3.Sub
Sup: a=11 b=hello
Sub constructor!!!

这段代码中,我主要想说一下第10行和第13行。

先说说this。在实例方法中,JVM会默认隐藏的传递一个参数,这个参数就是当前调用的实例本身,在方法内就可以通过this操作。

但是等等,在Sup的构造方法中,this却是jvm.test3.Sub类的实例。为什么???

从头再看初始化顺序:new Sub(11,"hello"),new指令会分配一块内存存放Sub对象的数据,然后返回一个引用(假设叫ref)指向这个对象。JVM会去调用Sub的构造方法,并将ref隐藏的传递给构造方法,所以在Sub的构造方法中的this就是ref。但是,Sub的构造方法先去调用父类Sup的构造方法,而JVM这时候隐藏传递进去的还是ref,还是指向Sub实例的引用。

但是又产生一个问题,竟然是Sub的实例,为什么能调用父类Sup的私有方法printMsg???

我想到一种解释:隐藏的参数的类型是本类型。什么意思?就是说在Sup类的所有方法中,隐藏的参数的类型是Sup。所以,当传来一个Sub类的引用ref的时候,进行了一次向上转型

虽然我觉得非常合理,但是还没有找到验证的方法。大家有懂的或者有其他的想法可以指正。 

            参考《深入Java虚拟机》

JVM与对象初始化的更多相关文章

  1. JVM中对象的创建过程

    JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...

  2. Java对象初始化详解

    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本 ...

  3. Java对象初始化详解(转)

    在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Java如何执行对象的初始化做一个详细深入地介绍(与对象初始化相同,类在被加载之后也是需要初始化的,本 ...

  4. Java类和对象初始化

    类的生命周期: Java类的初始化: 本阶段负责为类变量赋正确的初始值.(类变量即静态变量) Java编译器把所有的类变量初始化语句和静态初始化器通通收集到<clinit>方法中,该方法只 ...

  5. 【转】两道面试题,带你解析Java类加载机制(类初始化方法 和 对象初始化方法)

    本文转自 https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html 关键语句 我们只知道有一个构造方法,但实际上Ja ...

  6. java 复习整理(五 类加载机制与对象初始化)

    类加载机制与对象初始化   一 . 类加载机制 类加载机制是指.class文件加载到jvm并形成Class对象的机制.之后应用可对Class对象进行实例化并调用.类加载机制可在运行时动态加载外部的类, ...

  7. Java变量、Java对象初始化顺序

    局部变量与成员变量: 局部变量分为: 行参:在方法签名中定义的局部变量,随方法的结束而凋亡. 方法内的局部变量:必须在方法内对其显示初始化,从初始化后开始生效,随方法的结束而凋亡. 代码块内的局部变量 ...

  8. java类加载和对象初始化

    对象初始化过程:  1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化:  2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化:  3.其次,初 ...

  9. 【转】Java对象初始化详解

    来源:MySun 链接:http://mysun.iteye.com/blog/1596959 在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的.本文试图对Jav ...

随机推荐

  1. Java并发编程:线程的基本状态

    一.线程的基本状态 线程基本上有5种状态,分别是:NEW.Runnable.Running.Blocked.Dead. 1)新建状态(New) 当线程对象对创建后,即进入了新建状态,如:Thread ...

  2. 3.Redis常用命令:String

    字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中字符串类型的Value ...

  3. CSS3选择器~一看吓一跳,这么多不会

    复习CSS时发现很多选择器不会,因为平时很少用到.现在干脆一不做二不修,全部温习一遍.本文参考http://css.doyoe.com/. 一.元素选择器 图片来自:http://css.doyoe. ...

  4. 4日6日--Math的常用方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 《Python基础教程》第1章读书笔记

    # -*- coding:utf-8 -*- x = "hello " y = "world" print x+y print "hello &quo ...

  6. 使用FSharp 探索Dotnet图像处理功能1--反色变化

    坚持写博客是最近的目标.加油. 业余学习fsharp以来一直觉得这才是Dotnet开发,或者说所有开发者应该拥有的语言.配合Visual Studio的代码提示,即时执行窗口.开发程序有着极大的乐趣. ...

  7. .elf格式内容

    arm-linux-ld 可以将程序链接成我们arm平台下的可运行的程序 以之前使用过的led程序为例: 首先: arm-linux-gcc -g -c led.S (-g是表示产生调试信息, -c是 ...

  8. 卷积神经网络CNN公式推导走读

      0有全连接网络,为什么还需要RNN 图像处理领域的特殊性,      全连接网络缺点:                              RNN解决办法:      1参数太多       ...

  9. 从Chrome源码看JS Array的实现

    .aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line spa ...

  10. 基于51单片机IIC通信的PCF8591学习笔记

    引言 PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入.一个输出和一个串行I2C 总线接口.3 个地址引脚A0.A1 和A2 用于编程硬件地址,允许将最多8 个器件连接 ...