构造函数、构造代码块部分见解
昨天系统学习了构造函数,构造代码块方面的知识,现对所学知识进行一下梳理,首先我们先看这部分代码
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."<init>":()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."<init>":()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."<init>":()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对象的时候,如果存在构造代码块,默认执行一次构造代码块和构造函数