Java_代码块 总结
本篇文章主要是讲解代码块的基本概念、作用及执行顺序等内容。算是对代码块做一个初学的小总结。
概念
代码块:在Java中,使用{}括起来的代码被称为代码块。 代码块主要有:局部代码块、构造代码块、静态代码块。 其中,局部代码块和构造代码块统称为非静态代码块。 因此,本文主要是区别非静态代码块与静态代码块的执行步骤与区别。提示:以下是本篇文章正文内容,下面案例可供参考吖
一、作用
给所有对象进行初始化。
【补充】
代码块与构造器的区别:
(1)构造器主要是用于对象的初始化、创建对象。
(2)代码块只能给对象初始化,不能创建对象。
二、代码块的执行顺序
1.初始化的方式
代码块执行的大致顺序:
0、静态代码块在非静态代码块之前执行(静态代码块在整个流程只执行一次)
1、默认初始化
2、显式初始化 / 代码块初始化
3、构造器初始化
4、对象.属性访问
2.静态代码块 & 非静态代码块的初始化顺序
代码如下(示例):
public class CodeBlocks {
// 静态变量
public static int b = 2;
// 静态代码块
static {
A = 88;
System.out.println("这是静态代码块1,这里有一个A,是一个常量");
}
private static final int A;// 静态的常量
static {
// 静态的代码块不能访问非静态的属性
// a=1;
b = 22;
System.out.println("这是静态代码块2:这是常量A的值:" + A + "\t静态变量b:" + b + "\t");
}
// 非静态的代码块
{
a = 111;
b = 222;
System.out.println("这是非静态代码块1" + "" + "");
}
public int a = 1;// 非静态变量
{
a = 1111;
b = 2222;
System.out.println("这是非静态代码块1");
}
// 构造器
public CodeBlocks() {
// this.a = 11111; 是否用用this关键字均可
a = 11111;
b = 22222;
System.out.println("这是构造器的输出");
}
public CodeBlocks(int a) {
b = 001100;
System.out.println("这是构造器的输出");
}
// 方法
public void show() {
this.a = 111111;
b = 122222;
System.out.println("这是方法的输出:" + a + "\t" + b);
}
public static void main(String[] args) {
CodeBlocks codeBlocks1 = new CodeBlocks();
System.out.println("创建第一个对象时,最终输出的a:" + codeBlocks1.a + "\tb:" + b);
System.out.println();
CodeBlocks codeBlocks2 = new CodeBlocks();
System.out.println("创建第二个对象时,最终输出的a:" + codeBlocks2.a + "\tb:" + b);
System.out.println();
CodeBlocks codeBlocks3 = new CodeBlocks(98889);
System.out.println("创建第二个对象时,最终输出的a:" + codeBlocks3.a + "\tb:" + b);
codeBlocks1.show();
}
}
输出结果如下图
3.父类 & 子类中的代码块的执行顺序
//父类
public class Father {
public String fa1 = "父变量显式初始化";
public static String fa2 = "父静态变量显式初始化";
static {
fa2 = "父静态变量代码块静态初始化";
System.out.println(fa2);
}
{
fa1 = "父变量代码块非静态初始化";
fa2 = "父静态变量代码块非静态初始化";
System.out.println(fa1+" "+fa2);
}
public Father() {
this.fa1 = "这是构造器中的父变量";
fa2 = "这是构造器中的父静态变量";
System.out.println(fa1+" "+fa2);
}
}
//子类
public class Son extends Father {
static {
fa2 = "子静态变量代码块静态初始化";
System.out.println(fa2);
}
{
fa1 = "子变量代码块非静态初始化";
fa2 = "子静态变量代码块非静态初始化";
System.out.println(fa1 + " " + fa2);
}
public Son() {
fa1 = "这是构造器中的子变量";
fa2 = "这是构造器中的子静态变量";
System.out.println(fa1 + " " + fa2);
}
public static void main(String[] args) {
Father son = new Son();
}
}
执行的结果如下所示:
## 3.拓展——代码块的执行顺序
public class CodeBlock {
// 静态的对象1
public static CodeBlock codeBlock1 = new CodeBlock();
// 静态的对象2
public static CodeBlock codeBlock2 = new CodeBlock(1);
/**
* 静态代码块在静态对象的后面
*/
static {
System.out.println("这是静态代码块!");
}
public CodeBlock() {
System.out.println("这是构造器!");
}
public CodeBlock(int a) {
System.out.println("这是含参的构造器!");
}
{
System.out.println("这是非静态代码块!");
}
public static void main(String[] args) {
CodeBlock codeBlock = new CodeBlock();
}
}
public class CodeBlock {
// 静态的代码块在静态的对象前面
static {
System.out.println("这是静态代码块!");
}
// 静态的对象1
public static CodeBlock codeBlock1 = new CodeBlock();
// 静态的对象2
public static CodeBlock codeBlock2 = new CodeBlock(1);
public CodeBlock() {
System.out.println("这是构造器!");
}
public CodeBlock(int a) {
System.out.println("这是含参的构造器!");
}
{
System.out.println("这是非静态代码块!");
}
public static void main(String[] args) {
CodeBlock codeBlock = new CodeBlock();
}
总结
由上述可知,代码块执行的大致顺序为:
0、静态代码块在非静态代码块之前执行(静态代码块在整个流程只执行一次)
1、默认初始化
2、显式初始化 / 代码块初始化 (谁在上面谁先执行。即这2种初始化是同级的。)
3、构造器初始化
4、对象.属性访问
在有继承关系的父子类中,代码块的执行顺序为:
1、父类的静态代码块
2、子类的静态代码块
3、父类的构造代码块
4、父类的构造方法
5、子类的构造代码块
6、子类的构造方法
在这里,需要特别留意的是:
**只要是静态变量、方法,它执行的顺序都是从上到下执行。
**并不是每次都先从静态构造块开始执行。
就例如上述第3种例子:
1、静态的属性、方法、对象会在类加载的时候就编译。
2、而对象在创建的时候会执行非静态的代码块、构造方法。(类的方法需要调用才能执行)
3、如果先创建静态对象,它会先执行非静态的代码块、构造方法;后执行静态代码块。
4、如果是静态代码块在静态对象创建之前,则会先执行静态代码块。
本篇文章主要是通过分析静态代码块与非静态代码块的执行顺序。目前也只是初学。
因此,再次不做同步代码块的分析,以后再逐步深入的学习下,会补充此文档吖。
希望有更多的大佬能指点一下~