一、初始化块(代码块)
初始化块的表现形式为:{...}
初始化块的作用:对Java对象进行初始化
程序的执行顺序:1.声明成员变量的默认值。2.显示初始化、多个初始化块依次被执行(同级别下按先后顺序执行)。3.构造器再对成员进行赋值操作
package day15; public class Person { String name;//1.类的属性的默认初始化和显示初始化 public Person(){ this.name = "张三"; System.out.println("执行的是构造方法");//3.执行构造器的代码 } //非静态的代码块 { System.out.println("执行的是非静态代码块");//2.执行代码块的代码 } //非静态的代码块2 { System.out.println("执行的是非静态代码块2");//如果有多个非静态代码块,会按照从上到下的顺序依次执行 } }
package day15; public class Test { public static void main(String[] args) { new Person();//在new Person()执行的顺序 } }
打印结果为:
执行的是非静态代码块
执行的是非静态代码块2
执行的是构造方法
二、静态代码块
一个类中初始化块若有修饰符,则只能被static修饰,称为静态代码块(static block),当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
package day15; public class Person { String name;//1.类的属性的默认初始化和显示初始化 static int age; public Person(){ this.name = "张三"; System.out.println("执行的是构造方法");//3.执行构造器的代码 } //非静态的代码块 { System.out.println("执行的是非静态代码块");//2.执行代码块的代码 } //非静态的代码块2 { System.out.println("执行的是非静态代码块2");//如果有多个非静态代码块,会按照从上到下的顺序依次执行 } //静态代码块,先于非静态代码块执行 static{ //只能使用静态static修饰的属性和方法 age = 10; showAge(); System.out.println("==执行的是静态代码块=="); } public static void showAge(){//静态方法才能用在静态代码块中 System.out.println(age); } }
package day15; public class Test { public static void main(String[] args) { new Person();//在new Person()执行的顺序 new Person();//静态代码块只执行一次 } }
打印结果为:
三、非静态和静态代码块的比较
在实际开发中,static静态代码块用的多一点,用在初始化类的静态属性(static类型的属性)。
非静态代码块:没有static修饰的代码块
1.可以有输出语句。
2.可以对类的属性声明进行初始化操作。
3.可以调用静态和非静态的变量或方法。
4.若有多个非静态代码块,那么按照从上到下的顺序依次执行。
5.每次创建对象的时候,都会执行一次。且先于构造器执行。
静态代码块:用static修饰的代码块
1.可以有输出语句。
2.可以对类的属性声明进行初始化操作。
3.不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法
4.若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5.静态代码块的执行要先于非静态代码块。
6.静态代码块只执行一次。
四、静态代码块的作用
除了初始化类的静态属性,还可以处理比较复杂的静态方法:
package day15; public class TestPerson { String name; int age; }
package day15; public class Person { static TestPerson tp = new TestPerson();//创建一个静态方法 public Person(){ System.out.println("执行的是构造方法"); } //静态代码块 static{ //只能使用静态static修饰的属性和方法 age = 10; showAge(); System.out.println("==执行的是静态代码块=="); tp.name = "";//在静态代码块中进行初始化 tp.age = 20;//在静态代码块中进行初始化 } public static void showAge(){//静态方法才能用在静态代码块中 System.out.println(age); } }
五、非静态代码块的作用
package day15; public class Person { String name;//1.类的属性的默认初始化和显示初始化 public Person(){ this.name = "张三"; System.out.println("执行的是构造方法"); } public void test(){//创建一个新的test方法,方便创造内部类 System.out.println("这是Person的test方法"); } }
package day15; public class Test { public static void main(String[] args) { //匿名内部类 Person p = new Person(){//构建了一个没有类名的Person的子类,也就是匿名的Person的子类 //这种类没有类名,就不能用显示的new的方式创建对象,也没有构造器,如果还想要在构造器中初始化属性,就需要代码块{}实现 //由于匿名内部类是Person的子类,继承了父类的属性,现在想把name改成李四,但是不想动Person的代码 { //在匿名内部类中,就要用代码块来代替构造方法 super.name = "李四"; } public void test() {//重写test方法 // TODO Auto-generated method stub System.out.println("===="); //把父类Person的test()方法内容"这是Person的test方法"重写为"====" } }; System.out.println(p.name); p.test(); } }
打印结果为:
李四
====