代码块
介绍:代码块又称为初始化块,属于类中的成员(即是类的一部分),类似于方法,将逻辑语句封装在方法体中,通过{}包围起来
与类方法的不同点
-
无方法名
-
无返回类型
-
无参数
-
只有方法体,而且不用通过对象或类显示调用,加载类或者创建对象时隐式调用
一、代码块的基本使用
-
1. 修饰符可选,要写的话,只能写static
-
2. 代码块的分类
-
(1)静态代码块:使用static修饰
-
(2)普通代码块/非静态代码块:没有static修饰
-
3. 代码块的内容:可以为任何逻辑语句(输入,输出,方法调用,循环,判断等)
-
4. 对代码块的理解:相当于另外一种形式的构造器(对构造器的补充),可以做初始化的操作
-
应用举例:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的复用性
-
5. 使用说明:分号可有可无
{
System.out.println("我是末尾没有分号的代码块");
}
{
System.out.println("我是末尾带有分号的代码块");
};
二、代码块的使用细节(重点,难点)
-
(1)static 代码块也叫静态代码块,它随着类的加载而执行,并且只会执行一次。
-
(2)普通的代码块,在创建对象实例时,会被隐式调用。
-
创建一次,就会调用一次。
-
如果只是使用类的静态成员时,普通的代码块不会执行。
-
(3)类在什么时候被加载(非常重要!!!)
-
1. 创建对象实例时(new)
-
2. 创建子类实例时,父类也会被加载
-
3. 使用类的静态成员时(静态属性,静态方法)
-
(4)创建一个对象时,在一个类中的调用顺序(重点,难点)
-
1.调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)
-
2. 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)
-
3. 调用构造方法。
-
(4)构造器的调用
-
1. 隐含了super()
-
2. 调用普通代码块
-
注意:类的加载会完成静态属性的初始化和静态代码块的调用,所有构造器在类加载后调用
-
(5)创建一个子类对象(含有继承关系)时的调用顺序
-
一、类加载时,静态相关的内容
-
父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
-
子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
-
二、构造器的调用过程实现
-
父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
-
父类的构造方法
-
子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
-
子类的构造方法
-
总结:
-
1. 首先有继承关系,现有父类,后有子类
-
2. 构造器的调用顺序
-
(1)类加载---->静态代码块和静态属性的初始化(调用顺序看定义顺序)
-
(2)super()
-
(3)普通代码块的调用和普通属性的初始化
-
(4)构造器的调用
-
(6)静态代码块只能调用静态成员(静态属性和静态方法
三、代码示例:体会代码块的调用和类加载的过程
package codeblock;
public class main {
public static void main(String[] args) {
new b();
}
}
class a{
static {
System.out.println("调用 父类 的 static 代码块");
System.out.println();
test();
System.out.println("------------------------------------------");
};
{
System.out.println("========类加载完毕,静态相关内容初始化结束,进入 构造器 的初始化!!!========\n");
System.out.println("------------------------------------------");
System.out.println("调用 父类 的 普通 代码块");
System.out.println();
test();
test1();
System.out.println("------------------------------------------");
};
public a(){
System.out.println("调用 父类 的构造器");
System.out.println("------------------------------------------");
System.out.println();
System.out.println("===========该类的所有初始化工作结束,接着完成子类的初始化工作===========\n");
}
public static void test(){
System.out.println("调用 父类 中的 static类型 的 test()方法");
}
public void test1(){
System.out.println("调用 父类 中的 static类型 的 test1()方法");
}
}
class b extends a{
static {
System.out.println("调用 子类 的 static 代码块");
System.out.println();
test();
System.out.println("------------------------------------------");
System.out.println();
};
{
System.out.println("------------------------------------------");
System.out.println("调用 子类 的 普通 代码块");
System.out.println();
test();
test1();
System.out.println("------------------------------------------");
};
public b(){
System.out.println("调用 子类 的构造器");
System.out.println("------------------------------------------");
System.out.println();
System.out.println("===========该类的所有初始化工作结束,接着完成子类的初始化工作===========\n");
}
public static void test(){
System.out.println("调用 子类 中的 static类型 的 test()方法");
}
public void test1(){
System.out.println("调用 子类 中的 static类型 的 test1()方法");
}
}
输出结果
调用 父类 的 static 代码块
调用 父类 中的 static类型 的 test()方法
------------------------------------------
调用 子类 的 static 代码块
调用 子类 中的 static类型 的 test()方法
------------------------------------------
========类加载完毕,静态相关内容初始化结束,进入 构造器 的初始化!!!========
------------------------------------------
调用 父类 的 普通 代码块
调用 父类 中的 static类型 的 test()方法
调用 子类 中的 static类型 的 test1()方法
------------------------------------------
调用 父类 的构造器
------------------------------------------
===========该类的所有初始化工作结束,接着完成子类的初始化工作===========
------------------------------------------
调用 子类 的 普通 代码块
调用 子类 中的 static类型 的 test()方法
调用 子类 中的 static类型 的 test1()方法
------------------------------------------
调用 子类 的构造器
------------------------------------------
===========该类的所有初始化工作结束,接着完成子类的初始化工作===========
进程已结束,退出代码0