文章目录
- 1. 初始化块(代码块)的作用
- 2. 静态代码块
- 3. 非静态代码块和静态代码块的特点
1. 初始化块(代码块)的作用
作用:对java对象进行初始化
程序执行的顺序:
①声明成员变量的默认值 -->
②显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行) -->
③构造器再对成员进行赋值操作
举个例子:
Person类:
package day09;public class Person {String name;public Person() {//构造器this.name = "张三";System.out.println("执行的是构造方法");}//非静态的代码块{System.out.println("执行的是非静态代码块");}}
Test.java:
package day09;public class Test {public static void main(String[] args) {new Person();}
}
执行结果:
含代码块时,在new Person()时的执行顺序如下:
2. 静态代码块
一个类中初始化块若有修饰符,则只能被 static 修饰,称为静态代码块 (static block ) ,当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
例子:
Person类:
package day09;public class Person {String name;static int age;public Person() {this.name = "张三";System.out.println("执行的是构造方法");}//非静态的代码块{System.out.println("执行的是非静态代码块1");}{System.out.println("执行的是非静态代码块2");}{System.out.println("执行的是非静态代码块3");}//静态代码块static {//这里只能使用static修饰的属性和方法age = 1;showAge();}//静态方法public static void showAge() {System.out.println("===age为:" + age + ",执行了静态代码块,===");}}
Test.java:
package day09;public class Test {public static void main(String[] args) {new Person();new Person();//共new两次Person}
}
运行结果:
分析:
在程序运行过程中,非静态代码块每次new对象都又重新执行,静态代码块只执行一次。
3. 非静态代码块和静态代码块的特点
非静态代码块 没有static修饰代码块 | 静态代码块 用static修饰的代码块 |
---|---|
可以有输出语句 | 可以有输出语句 |
可以对类的属性声明进行初始化操作 | 可以对类的属性声明进行初始化操作 |
可以调用静态和非静态的变量或方法 | 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法 |
若有多个非静态代码块,则按照从上到下的顺序依次执行 | 若有多个静态代码块,则按照从上到下的顺序依次执行 |
每次创建对象的时候,都是执行一次。且先于构造器执行 | 静态代码块的执行要先于非静态代码块 |
非静态代码块每new一次就执行一次 | 静态代码块只执行一次 |
在实际开发中,static静态代码用在初始化类的静态属性(static类型属性)。
举例:
创建一个TestPerson类:
package day09;public class TestPerson {int age;String name;}
Test.java:
package day09;public class Person {String name;static int age;static TestPerson tp = new TestPerson();//静态代码块static {//static静态代码初始化TestPerson()类的静态属性tp.name = "";tp.age = 1;}}
下面授课老师讲的一个例子,有点难:
Person类:
package day09;public class Person {String name;static int age;public Person() {this.name = "张三";System.out.println("执行的是构造方法");}public void test() {System.out.println("Person的test方法");}}
Test.java:
package day09;public class Test {public static void main(String[] args) {//匿名内部类Person p = new Person() {@Overridepublic void test() {System.out.println("====");}}}
}
运行结果:
说明:
问题:现在想把name改成李四,但是不想动Person的代码
答: 用代码块代替构造方法
Person类:
package day09;public class Person {String name;static int age;static TestPerson tp = new TestPerson();public Person() {this.name = "张三";System.out.println("执行的是构造方法");}public void test() {System.out.println("Person的test方法");}}
Test.java:
package day09;public class Test {public static void main(String[] args) {//匿名内部类Person p = new Person() {//这是一个Person的匿名子类//问题:现在想把name改成李四,但是不想动Person的代码//答: 用代码块代替构造方法{//再匿名内部类中,用代码块代替构造方法super.name = "李四";}@Overridepublic void test() {System.out.println("====");}};System.out.println(p.name);p.test();//上面重写了test方法}
}
运行结果: