构造函数、构造代码块部分见解

构造函数、构造代码块部分见解

昨天系统学习了构造函数,构造代码块方面的知识,现对所学知识进行一下梳理,首先我们先看这部分代码

package com.imooc.concurrent;

public class Demo1 {


    public Demo1() {
        // TODO Auto-generated constructor stub
        i=30000;
    }
    int i =10000;
    public static void main(String[] args) {
        Demo1 d1 =new Demo1();
        Demo1 d2 =new Demo1();
        Demo1 d3 =new Demo1();
        System.out.println(d1.i);


    }

}

如上代码所示,我的第一反应是会报错,但是程序运行的结果30000,我们通过对代码的反编译(反编译命令(jdk8.0版本):javap -l -c -p Demo1),我们的运行结果为

Compiled from "Demo1.java"
public class com.imooc.concurrent.Demo1 {
  int i;

  public com.imooc.concurrent.Demo1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: aload_0
       5: sipush        10000
       8: putfield      #2                  // Field i:I
      11: aload_0
      12: sipush        30000
      15: putfield      #2                  // Field i:I
      18: return
    LineNumberTable:
      line 5: 0
      line 9: 4
      line 7: 11
      line 8: 18
 }

我们发现程序先执行了声明赋值语句int i = 10000,接着,我们再看下面的代码

package com.imooc.concurrent;

public class Demo1 {

    public Demo1() {
        i=30000;
    }
    int i =10000;
    {
        i=20000;
    }
    public static void main(String[] args) {
        Demo1 d1 =new Demo1();
        Demo1 d2 =new Demo1();
        Demo1 d3 =new Demo1();
        System.out.println(d1.i);

    }

}

经过反编译,运行结果为:

Compiled from "Demo1.java"
public class com.imooc.concurrent.Demo1 {
  int i;

  public com.imooc.concurrent.Demo1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: aload_0
       5: sipush        10000
       8: putfield      #2                  // Field i:I
      11: aload_0
      12: sipush        20000
      15: putfield      #2                  // Field i:I
      18: aload_0
      19: sipush        30000
      22: putfield      #2                  // Field i:I
      25: return
    LineNumberTable:
      line 5: 0
      line 8: 4
      line 10: 11
      line 6: 18
      line 7: 25

我们通过上面的实例发现,当存在构造函数的时候,声明初始赋值变量第一次执行,无论你将该初始赋值语句放在哪里,而构造函数总是最后一次执行,无论你将该函数放在哪里,接着,当我们去掉显式构造函数之后,我们看下面的代码

public class Demo1 {

    {
        i=20000;
    }
    int i =10000;
    public static void main(String[] args) {
        Demo1 d1 =new Demo1();
        Demo1 d2 =new Demo1();
        Demo1 d3 =new Demo1();
        System.out.println(d1.i);

    }

}

程序运行的结果为10000,我们经过反编译之后

Compiled from "Demo1.java"
public class com.imooc.concurrent.Demo1 {
  int i;

  public com.imooc.concurrent.Demo1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: aload_0
       5: sipush        20000
       8: putfield      #2                  // Field i:I
      11: aload_0
      12: sipush        10000
      15: putfield      #2                  // Field i:I
      18: return
    LineNumberTable:
      line 3: 0
      line 10: 4
      line 12: 11

我们发现程序是按顺序进行执行的,所以,在显式构造函数不存在的时候,我们的程序是按顺序执行的。

总结

  • 1.当存在显式构造函数,构造代码块,声明式赋值语句时,程序默认先执行声明式赋值语句,最后执行构造函数
  • 2.当不存在显式构造函数时,程序是按顺序执行的

备注

  • 在java中每次new对象的时候,如果存在构造代码块,默认执行一次构造代码块和构造函数

你可能感兴趣的:(构造函数、构造代码块部分见解)