Java中代码块主要分为四种:
在方法中出现{ }的就是普通代码块
在类中出现的{ }的就是构造代码块
使用static关键字修饰的{}是静态代码块
还有就是线程中使用的同步代码块(synchronized)
普通代码块
package Test03;
public class Demo02 {
public static void main(String[] args) {
{
int a=20;//1
System.out.println(a);
}
int a=30;//2
System.out.println(a);//3
}
}
注意1处定义的a范围只在{}里面,假如删掉2处的语句,3处会报错,没有变量a.
构造代码块
构造代码块优先于构造方法执行,且执行多次,只要new一个对象,就会执行一次构造块中的内容。
静态代码块
静态块优先于主方法执行,如果在普通类中定义的静态块,优先于构造块执行,不管不多少个实例化对象产生,静态代码块只执行一次,静态代码块的主要功能就是为静态属性初始化。并且静态代码块不能定义在方法中。
静态代码块与静态方法的区别
静态代码块是自动执行的,而静态方法是被调用的时候才执行。
一般情况下,如果有些代码必须在项目启动的时候就执行,就使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化。
当在没有创建对象的情况下,来调用方法的时候,需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用。
package Test03;
public class Demo3 {
static{
System.out.println("自动执行!");
}
public static void main(String[] args) {
}
}
结果:
自动执行!
静态方法补充
1、静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。因为对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。
2、 静态方法不能以任何方式引用this和super关键字,因为静态方法在使用前不用创建对象,当静态方法调用时,this所引用的对象根本没有产生。
3、静态变量是属于整个类的,而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态。(可以对比为什么static代码块不能定义在方法中)
下面是一道面试题:请问输出什么?
package Test03;
class HelloA {
public HelloA(){
System.out.println("这是父类的构造方法!");
}
{
System.out.println("I'm A class");
}
static{
System.out.println("static A");
}
public void show(){
{
System.out.println("hello");
}
}
}
package Test03;
public class HelloB extends HelloA{
public HelloB(){
System.out.println("这是子类的构造方法!");
}
{
System.out.println("I'm B class");//这是构造代码块,在new对象的时候,构造代码块优先于构造方法执行
}
static
{
System.out.println("static B");//这是静态代码块,静态代码块优先于主方法执行,优先于构造方法执行
}
public static void main(String[] args) {
{
System.out.println("A");
}
System.out.println("hello!");
new HelloB();
{
System.out.println("B");
}
}
}
结果:
static A
static B
A
hello!
I’m A class
这是父类的构造方法!
I’m B class
这是子类的构造方法!
B
先执行父类的静态代码块,在执行子类的静态代码块,然后执行主方法,执行主方法中第一个普通代码块,再打印hello,当new一个对象后,先执行父类的构造代码块,在执行父类的构造方法,在执行子类的构造代码块,在执行子类的构造方法,在执行主方法中第二个普通代码块。
注意调用子类的构造方法时,子类的构造方法会默认先调用执行父类的构造方法,再执行子类的构造方法。
总结:执行优先顺序 静态代码块>主方法>构造代码块>构造方法