java 类中初始化和构造函数的过程

转载 2018年04月16日 21:15:22

本人小白一枚,看java类的初始化的时候好晕的说,我觉着书上尽管说的对。但总认为有些信息没说出来,没说清楚,看了好多文章博客的,如今有些感悟,来小写下总结,也算是为以后再次复习种个好果子。

先摘一下书上写的:

载入:将类的class文件读入内存,并为之创建一个java.lang.class对象。

连接:把类的二进制数据合并到JRE中,检查被载入的类是否有正确的内部结构,并和其它类协调一致。为类的静态FIELD分配内存,设置默认值,将类的二进制数据中的符号引用替换成直接引用。

初始化:主要对静态Field进行初始化。初始化方式两种:声明静态Field时指定的值。使用静态初始化块为其指定初始值。JVM会按他们的顺序运行。初始化包含下面步骤:
如果该类没有被载入和连接。则先载入并连接该类。
如果他的父类没有被初始化。则先初始化他的父类
如果类中有初始化语句,则系统依次运行。

看完之后我脑子里一直就盘旋着几个问题:

    1、类的载入和初始化神马的和构造函数有啥关系和差别?

    2、类的初始化会为实例属性分配内存吗?

    3、假设我要创建一个实例对象。究竟是怎么个创建流程?

OK,假设你也有以上的疑问,那么我们一起来看看究竟是怎么回事!我会直接回答最后一个问题,当你把这个问题弄明确了,前面的就迎刃而解了。

  public class Person{

  static{staticInt = 6; }

  {vInt =15;  }

   static int staticInt = 3;

   int vInt = 10;

   Person(){

    staticInt = 9;

     vInt = 20;

    }

}

    Person  p = new Person();

JVM会看:

1)哎,有个变量p。然后就给它分配一个空间(这里的空间指的是指针,而不是实际的对象)

2)分完了以后发现它须要Person这个类来进行实例化,然后就到内存里找。看这个类有没有被载入到内存里来,假设有救直接用了。假设没有就会进行载入。我们就来说没有的情况

3)载入的时候。将类的class文件读入内存。并为之创建一个java.lang.class对象。

这里须要重点说一下。在创建这个对象的时候,就会保存这个类的全部信息。比方这个类有哪些属性(静态的非静态的都包含)。有哪些方法(静态的非静态的都包含),有什么代码块。都会被记录。

4)把类的二进制数据合并到JRE中。检查被载入的类是否有正确的内部结构,并和其它类协调一致。JVM跑到java.lang.class对象里看看,都有啥静态变量。为他们分配内存。设置默认值,将类的二进制数据中的符号引用替换成直接引用。

5)然后对静态Field进行初始化,初始化方式两种:声明静态Field时指定的值。使用静态初始化块为其指定初始值。JVM会按他们的顺序运行。这个地方须要注意:如上代码,静态的变量staticInt最后会被赋值为3,由于静态代码块在声明之前。JVM是先跑到java.lang.class对象看有什么静态变量,给他分个空间,然后再运行的声明和静态代码块语句。因此初始化之后值为3.

好了,345都是类的载入和初始化。我们再来看看都做了些什么:生成java.lang.class对象。有该类里的属性方法代码块的全部信息。再为静态属性分配了内存并运行了静态代码块。按

顺序把静态属性给初始化了。

这里并没有为非静态属性分配内存,也没有运行构造函数和非静态代码块,一句话

总结就是:记录下这个类的全部属性和方法代码块等信息。为静态的变量分内存并赋值

初始化之后,如今JVM改依据这个初始化好的类信息来进行实例化了。先前被初始化好的静态变量会被全部实例共享。静态代码块将不会再被运行,相当于失效了。我们来看看JVM接下来要干嘛?

6)JVM跑到java.lang.class对象里看一看。有哪些实例变量须要分配内存的,跟静态变量类似的,JVM先给实例变量分内存,分完之后,运行代码块和声明,在这里vInt为10。

7)最后运行构造函数,运行完后。vInt变成了20,staticInt变成了9,然后改构造函数隐性的返回一个Person实例对象给变量p。     

好了。讲完了,我们再看看12问题

1、类的载入和初始化神马的和构造函数有啥关系和差别?

仅仅要在类须要实例化的时候才会运行构造函数。而类的载入和初始化却在这些情况都会被运行:创建实例  调用静态方法  訪问某个静态Field(假设该变量还是final的,则在编译阶段就能确定下来,就不会初始化)   初始化某个类子类

2、类的初始化会为实例属性分配内存吗?

不会为实例属性分配,仅仅有在实例化的时候才会分内存

总结

1)将类的class文件读入内存,并为之创建一个java.lang.class对象。

2)把类的二进制数据合并到JRE中。检查被载入的类是否有正确的内部结构。并和其它类协调一致,并为静态变量分内存

3)为静态变量初始化赋值

以上为初始化顺序

4)为非静态变量分内存。并赋值

5)构造函数,返回构造好的对象


假设有子类父类关系的时候:

父类和子类的class文件都载入到内存,当父类。和子类有Static时。先初始化Static,再初始化子类的Static,

再初始化父类的其它成员变量->父类构造方法->子类其它成员变量->子类的构造方法。

有不正确的地方还望高手指出啊

Java 代码块、成员变量初始化、构造函数初始化顺序

一、对于实例变量 实例变量初始化过程分析 初始实例变量的有: ① 实例变量定义时初始化、 ② 非静态代码块初始化、 ③ 构造函数实例变量初始化 package cn.daywan.test; ...
  • Only_Wan
  • Only_Wan
  • 2016-11-23 16:51:38
  • 1818

java类的初始化和构造函数

本人小白一枚,看java类的初始化的时候好晕的说,我觉着书上虽然说的对,但总觉得有些信息没说出来,没说清楚,看了好多文章博客的,现在有些感悟,来小写下总结,也算是为以后再次复习种个好果子。     先...
  • strong815
  • strong815
  • 2015-07-24 15:44:24
  • 3388

深入理解Java对象的创建过程:类的初始化与实例化

在Java中,一个对象在可以被使用之前必须要被正确地初始化,这一点是Java规范规定的。在实例化一个对象时,JVM首先会检查相关类型是否已经加载并初始化,如果没有,则JVM立即进行加载并调用类构造器完...
  • justloveyou_
  • justloveyou_
  • 2017-05-18 14:17:45
  • 17224

Java 构造方法和成员变量初始化顺序

一定要注意,成员变量按照其声明的顺序会被初始化, 并且立刻被初始化为二进制的0,这个动作发生在所有事件之前, 也就是编译器会立刻将分配给对象的空间初始化。 最后就是调用类的构造方法了。 ...
  • a916879788
  • a916879788
  • 2017-01-12 19:41:50
  • 3104

Java中的构造函数与字段初始化顺序

在java中我们通过new ClassName()来创建对象,那么创建对象的整个过程是怎么样的呢?其实,在创建对象时, 首先虚拟机会为对象的所有字段分配内存, 包括哪些从父类继承来的字段, 而且会把这...
  • bboyfeiyu
  • bboyfeiyu
  • 2014-03-24 17:09:04
  • 2813

java含参构造函数初始化

package com.mejustdoit; public class Component1 { public Component1(int i) { // TODO Auto-generate...
  • mejustdoit
  • mejustdoit
  • 2015-07-08 17:01:10
  • 1615

在类的对象的初始化中为什么需要构造函数?

//类需要构造函数 类是一种抽象结构,而不是一种实体,并不占用存储空间。所以在定义类结构体的时候,是不可以对类中的成员进行初始化的。 例如以下的做法就是错误的: class student{ ...
  • zhhymh
  • zhhymh
  • 2011-03-10 09:31:00
  • 2131

Java中数组的初始化的含义

Java中数组的初始化的含义引用数组的定义为(如果不是基本的数据类型):   Obj[] a=new obj[size]下面首先来看这个例子class showstr{    public void ...
  • metasearch
  • metasearch
  • 2005-11-25 16:37:00
  • 2306

带参构造函数的类对象数组初始化

带参构造函数的类对象数组初始化
  • xhjcehust
  • xhjcehust
  • 2015-01-07 18:47:01
  • 3974

c++类的构造函数两种初始化成员方式的区别

类的构造函数在初始化成员时,有以下两种方式: 方式一: CSomeClass::CSomeClass()  {     x=0;     y=1;  }  方式二: CSomeClass::CSo...
  • fengxinlinux
  • fengxinlinux
  • 2017-04-12 19:34:56
  • 2635
收藏助手
不良信息举报
您举报文章:java 类中初始化和构造函数的过程
举报原因:
原因补充:

(最多只允许输入30个字)