本文不再以ClassLoader的视角解释这些问题。

首先,Java代码有个特点,就是成员变量可以在前面的方法中使用,在后面定义。这一特性,很多人说Java了不起,可是为什么呢?Java为何能够这样呢?

我们首先来看一道面试题:

写出上面代码的运行结果。
其实对于Java了解比较深入的人,不屑于解决这道题,因为看代码写运行结果,再常规不过,可是这个题,要是写准了,还真的不容易,因为,我们要以类似C语言的视角审视这道题。
OK,我们首先理解一个基本概念,内存空间一定是先申请,再初始化,再使用的。例如C语言中的malloc分配空间,然后初始化写0,然后使用。其实Java也是如此的。
首先,我们从main方法入手,只有一行new对象(第26行)。
new对象首先要加载类,这是肯定的了,因此“Test”需要加载类,也就是加载Test的字节码文件到方法区(永久代)中。这时需要把类中的“static”部分处理完成。
也就是说,static部分是随着Test的字节码文件进入到永久代的。
它的过程是:先把所有的static部分申请空间,然后再给每一个static成员由上至下分配初始值。初始值有两种,一种是Java对于基本数据类型的默认初始值,这个默认初始值在申请空间之时就给每一个成员赋予了,另一种是Java程序员利用“=”对成员进行赋初始值。
如图所示,五个静态成员在永久代首先被分配内存。
此时,k=0,t1=null,t2=null,i=0,n=0。空间申请完成之后,我们把0赋值给k,虽然k被分配内存之后就是0,但是依然还要把0再赋值给k,因为“=”右边的“0”是程序员对k的赋值。然后是给t1实例一个对象,也就是t1原本是null,现在把new出来的对象赋值给t1,于是就要构建一个Test对象。构建对象时,要把所有的非static部分初始化一份,放入堆内存。
这时,你就理解了Java语法中,为什么静态成员是“类名.成员”,而非静态成员是“对象.成员”了。因为所属关系不同。
那么我们开始找非静态的成员
如图,有j和一个构造块。
因此是先给j申请空间,然后运行print("j")方法,把方法的返回值交给j。
于是,这个程序的第一段打印结果出来了:
打印:
此后,k=1 , n=1 , i=1。
然后是接着找非静态的部分,就只有构造块了,因此是:
此后,k=2 , n=2 , i=2。
这时,我们构造对象的准备工作做完了,也就是非静态的代码都执行完了,因此开始实例化对象,Java实例化对象使用构造方法,因此执行:
打印:
此后,t1不再是null,然后初始化t2,过程和t1一样,因此运行结果是:
再然后初始化静态的i,因此是执行:
输出打印:
然后初始化 n(第6行),直接把n赋值为99。但是什么都不打印。
然后再往下是静态块:
输出打印:
至此,所有的静态部分也都初始化完毕了,可以new Test("init")了:
输出打印:
所以总体打印如下:
总结,其实Java本身也是代码从上往下走的,只不过静态部分和非静态部分在两个次元里。Java的成员有分配空间,赋默认值两个过程,且首先为全体成员申请空间,然后由上至下逐一赋值。

Java类与对象初始化的过程(一道经典的面试题)的更多相关文章

  1. Java类和对象初始化

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

  2. Java中子类对象初始化的过程

    Java中的继承机制看似简单,实际上包含了很多细节.最近在刷题过程中屡屡跳坑,于是自己仔细再学习了一下Java中子类初始化的细节,与大家分享. class Father { Father(){}; } ...

  3. 解析Java类和对象的初始化过程

    类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...

  4. [转载]解析 Java 类和对象的初始化过程

    原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-clobj-init/index.html 由一个单态模式引出的问题谈起 类的初始化和对象初始化 ...

  5. JAVA 对象初始化的过程

    对象初始化的过程例:Student S    =    new Student();1.因为new Student()用到了Student类,所以会把它从硬盘上加载进入内存2.如果有static静态代 ...

  6. [Java初探08]__简单学习Java类和对象

    前言 在前面的学习中,我们对面向对象的编程思想有了一个基本的了解,并且简单的了解了类和对象的定义.那么类和对象在Java语言中是如何表现的,这次,就从实际出发,学习一下一下类和对象在Java语言中的使 ...

  7. java类的成员初始化顺序和初始化块知识

    java类的成员初始化顺序和初始化块知识 转自:http://blog.csdn.net/lgfeng218/article/details/7606735 属性.方法.构造方法和自由块都是类中的成员 ...

  8. Java 类成员的初始化顺序

    Java 类成员的初始化顺序 前言:开发中碰到一个Java文件中有很多的成员变量,包括静态和非静态的,还有很多的初始化方法,很好奇这些成员的初始化顺序,在这里作个研究.   1  无继承情况下的Jav ...

  9. java类和对象之间的差

    java类和对象之间的差别是一个普遍的问题,刚开始学习java当它来到与类和对象接触.今天就来总结一下它们之间的差异. 先说说class和object差异.事实上,词:object是全部class的父 ...

随机推荐

  1. Spring里的Ant Pattern

    Spring里的Ant Pattern用于匹配URL 可以参考官网:https://docs.spring.io/spring/docs/current/javadoc-api/org/springf ...

  2. NMS_非极大值抑制(转)

    NMS(non maximum suppression),中文名非极大值抑制,在很多计算机视觉任务中都有广泛应用,如:边缘检测.目标检测等. 这里主要以人脸检测中的应用为例,来说明NMS,并给出Mat ...

  3. 第一章javascript简介

    javascript 当诞生于1995 最开始是目的是处理在服务器端进行的表单验证:让其在服务器端验证改为在服务端验证,大大提高速度(当时网络慢) 如今javascript是一门功能全面的语言,包含闭 ...

  4. java——链表映射 LinkedListMap

    好像也不是基于链表来实现的,而是采用与链表类似的节点形式重新定义了一个节点内部类,以此来实现映射 public class LinkedListMap<K, V> implements M ...

  5. Django-1 简介

    1.1 MVC与MTV模型 MVCWeb服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负 ...

  6. (转)轻松掌握shell编程中数组的常见用法及示例

    缘起:在老男孩进行linux培训shell编程教学中,发现不少水平不错的网友及同学对数组仍然很迷糊,下面就给大家分享下数组的用法小例子,希望能给大家一点帮助.其实SHELL的数组很简单,好用.我们学习 ...

  7. 关于老教授之家项目的思考 && 中国互联网+大赛培训

    最近在做中国互联网+竞赛相关的项目,有一点思考在这里记录下来,算是一份经历,日后可以再回顾,这也是我真正参加的一个大型比赛,作为技术人员可能更多的是从事技术,但是在其他方面能贡献自己的一份力量也是不错 ...

  8. MongoDB + express + node + bootstrap 搭建多人博客

    这篇博客讲述如何搭建一个多人博客,需要一定的基础知识,用于思路整理和备忘. 第一步: 新建文件夹 blog ,结构如下: bin --- 可执行二进制文件,最终的启动接口. models --- 存储 ...

  9. Nginx实践:(1) Nginx安装及日志配置

    1. 安装 (1)  Nginx下载地址:https://nginx.org/download/nginx-1.14.0.tar.gz (2)  安装时可能出现依赖库不存在,比如prec包,可以使用y ...

  10. 调用webservice

    WebClient web = new WebClient(); Stream stream = web.OpenRead(this._wsdlUrl); //Stream streamInfo = ...