一,代码块的引入
1,定义:代码块就是指程序中被大括号括起来的代码
2,分类:
静态代码块(重点)
构造代码块(初始化代码块) (熟悉)
局部代码块 (了解)
同步代码块(在其后的线程讲解)
class T{
int a=10;
static{
//静态代码块
}
public void test(){
{
//局部代码块
}
}
{
//构造代码块
}
}
二,局部代码块
局部代码块的最大作用是再细粒度的控制局部变量的作用域。
class T1{
int a;
public T1(){}
public void test(){
int b=10;//定义局部变量
{
//局部代码
int b=10;
}
/*
局部变量b是写在局部代码块中;
它的作用域范围是局部代码块的大括号里。
所以以下的语句会出现报错
System.out.println("b="+b);//输出局部变量b
*/
}
}
三,静态代码块
1,静态代码块的执行时机
静态代码块是在类的加载过程中被执行的。
因为静态变量的创建、默认初始化、显示初始化和静态代码块的执行都在类的记载
过程完成,所以要区分它们之间的执行顺序。
因为静态成员变量不开辟空间就不能使用,所以肯定是静态成员量先被开辟空并默认初始化。
而显示初始化和静态代码块要看类中定义顺序,哪个在前面,就先执行哪个。
注意:通常编码过程中都是先写属性,所以一般情况下都是先执行静态成员变量的显示初始化,
再执行静态代码块。
2,静态代码块中调用静态和非静态的规则:
静态代码块中只能调用静态成员,不能调用非静态成员。
3,静态代码块属于类的。
4,静态代码块是随着的类的加载而执行
因为类只在第一次使用前被加载到内存,所以静态代码块在程序执行过程中,只在类的加载过程
执行,只执行一次。
5,静态代码块肯定在构造方法之前先执行。
6,如果一个类的定义中有多个静态代码块,则会按照定义的先后顺序执行。
7,静态代码块使用目的?(重要)
某个资源在系统中如果只需要加载一次,并可以多次使用,则可以考虑静态代码块加载此资源。
class T2{
int a=10;
static int b=20;
static{
System.out.println("这是T2类的静态代码块2");
//System.out.println("a="+a);//静态代码块中不能调用非静态成员变量
System.out.println("b="+b);静态代码块中能调用静态成员变量
//b=30;
}
ststic{
Syste.out.println("这是T2类的静态代码块1");
}
public T2(){
System.out.println("b="+b);
}
public static void test(){
System.out.println("这是T2类的静态成员方法test");
}
}
public class codeBlockDemo{
public static void main(String[] args){
//静态代码快的执行时机
//创建一个T2类的对象
T2 tt=new T2();//输出T2类的静态代码块
//以上的创建T2类对象的代码块可以证明静态代码是在使用对象之前执行。
//又因为使用对象前分加载和创建两个步骤,
//可以使用直接调用静态方法的方式再区分。
T2 . test();//这是T2类的静态代码块。
//以上代码只是使用T2类,并没有创建对象,输出信息可以证明静态代码块是
//在类的加载过程中被执行的。
//静态代码块的执行次数
T2 . test();//静态代码块只是在类的加载时执行,类只是在第一次使用前加载。
T2 tt =new T2();
T2 . test();
T2 tt=new T2();
//再深入了解静态变量和静态代码块之间 的关系
T2 tt=new T2();
//测试多个静态代码块之间的执行顺序
T2 . test();
}
}
四,构造代码块
1,执行时机
构造代码块是在创建对象的过程中执行的。
构造代码块肯定是在构造方法之前执行的。
构造代码块和普通成员的执行顺序需要根据在类的定义顺序决定,
如果先定义普通成员变量的初始化,则显示初始化先执行。否则,构造代码块先执行。
注意:在编写程序时通常都是先写成员变量,所以往往都是成员变量的显示初始化早于构造代码块执行
2,执行次数
每创建对象就输出一次。
3,构造代码块属于对象的。
4,构造代码块是随着对象的创建而执行。
class T3{
int a=10;
{
System.out.println("这是T3类的构造方法");
System.out.println("a="+a);
}
public static void test(){
System.out.println("这是T3类的静态成员方法test");
}
}
public class CodeBlockDemo1{
public static void main(String[] args){
//构造代码块执行时机
//创建T3类的对象
T3 tt=new T3();//这是T3类的构造代码块
//再次区分是在加载阶段还是创建对象阶段执行?
T3 . test();//T3类的静态成员方法test
//以上代码构造代码块中的输出语句没有执行,说明构造代码块是在创建对象的过程执行的。
//再次区分 普通成员变量的显示初始化 构造代码块 构造方法它们之间的执行顺序
//构造代码块和构造方法的执行顺序:构造代码块先执行,然后再构造方法。它俩是优先级问题。
//普通成员变量的显示初始化和构造代码块肯定在构造方法之前执行,而普通成员变量的显示
//初始化和构造代码则是顺序问题。
T3 tt=new T3();
//执行次数
T3 tt=new T3();
T3 tt=new T3();
T3 tt=new T3();
//以上代码的输出是每创建一个对象就输出一次。
}
}
五,静态代码块、构造代码块、构造方法之间的执行顺序。
1,静态代码块 类的加载阶段
2,构造代码块 创建对象阶段
3,构造方法 创建对象阶段
六,代码块练习题
class T4{
int a;
int b;
static{
System.out.println("这是T4类的静态代码块1");
}
{
System.out.println("这是T4类的构造代码块1");
}
public T4(){
System.out.println("这是T4类的无参构造方法");
}
public T4(int a,int b){
this();
System.out.println("这是T4类的带参构造方法");
this.a=a;
this.b=b;
}
{
System.out.println("这是T4类的构造代码块2");
}
{
System.out.println("这是T4类的静态代码块2");
}
public static void tets(){
System.out.println("这是T4类的静态成员方法test");
}
}
public class CodeBlockDemo2{
public static void main(String[] args){
//创建T4类的对象
//以下代码是第一次使用类,涉及加载类和创建对象
//加载类:静态代码块
//创建对象:构造代码块先执行,再构造方法
T4 tt=new T4();
T4 . test();//调用静态成员方法test
//按照顺序写出以上代码执行时的输出的顺序语句?
/*
1,这是T4类的静态代码块1
2,这是T4类的静态代码块2
3,这是T4类的构造代码块1
4,这是T4类的构造代码块2
5,这是T4类的无参构造方法
6,这是T4类的带参的额构造方法
7,这是T4类的静态成员方法test
*/
}
}