java中的静态 && 代码块

java中的静态修饰符

修饰符static: 是一个关键字,用于修饰成员变量和成员方法

特点

  • 被所有对象共享
  • 可以使用类名调用
  • 静态加载优先于对象
  • 随着类的加载而加载

注意事项

  1. 静态方法

    静态方法只可以调用静态的成员(包括方法和变量)

  2. 非静态方法

    既可以调用非静态方法和变量,也可以调用静态的方法和变量

  3. 由于静态方法优先于对象创建,故静态方法中没有this对象

使用场景

static常用来修饰工具类中的方法和变量,例如JDK中Math工具类等。

java中的代码块

基本概念

形式如下:

1
2
3
4
5
{
System.out.println("这是一个java代码块");

......
}

分类:

  1. 局部代码块

    和局部变量类似,出现在方法内部,主要用于限制变量和方法的作用域,即代码块外不能访问代码块中的变量和方法

  2. 构造代码块

    和类中的构造方法类似,出现在类内部,用来存放基于类的所有对象的公共代码部分,可以降低代码冗余度,会随着对象的创建自动调用

  3. 静态代码块

    和静态方法类似,出现在类内部,用来存放类中需要初始化的一些代码(如驱动),随着类的加载而加载,并且自动调用

  4. 同步代码块

    用于不同线程间的同步问题

一个static和代码块的面试题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class BlockTest {
static {
System.out.println("BlockTest静态代码块执行");
}

{
System.out.println("BlockTest构造代码块执行");
}


public BlockTest(){
System.out.println("BlockTest无参构造执行了");
}

public static void main(String[] args) {
System.out.println("BlockTest的主函数执行了");
Coder c = new Coder();
Coder c2 = new Coder();
}
}

class Coder {

static {
System.out.println("Coder静态代码块执行");
}

{
System.out.println("Coder构造代码块执行");
}

public Coder() {
System.out.println("Coder无参空构造执行");
}

}

问题:代码如上,请写出程序的执行顺序

分析如下:

​ 首先,程序启动,JVM会加载main函数所在类,即BlockTest这个类,这时候它的静态代码块随之加载并自动执行,打印"BlockTest静态代码块执行"。由于main的调用是基于类的加载,并未实例化BlockTest,故其局部代码块和构造方法都不会执行。

​ 接着,调用main函数,打印"BlockTest的主函数执行了"。接着执行Coder c = new Coder(),会加载Coder类,调用其静态代码块,打印"Coder静态代码块执行"。随后,在生成c对象中,首先调用其类中代码块,打印"Coder构造代码块执行",然后调用其构造方法,打印"Coder无参空构造执行"

​ 最后,执行Coder c2 = new Coder(),和上面类似。不同的是,这时Coder类已经加载,故不会再次调用其静态代码块。但再次生成了一个新的对象c2,因此会调用其类中代码块,打印"Coder构造代码块执行",接着调用其构造方法,打印"Coder无参空构造执行"

​ 总结:整个程序的打印输出为:

1
2
3
4
5
6
7
BlockTest静态代码块执行
BlockTest的主函数执行了
Coder静态代码块执行
Coder构造代码块执行
Coder无参空构造执行
Coder构造代码块执行
Coder无参空构造执行