package com.btp.t2;/* * 类的第四个成员:初始化块(代码块) * 1.代码块如果有修饰的话,那么只能使用static * 2.代码块分类: * ①静态代码块(static修饰): * 1.里面可以有输出语句 * 2.随着类的加载而加载,而且只被加载一次 * 3.多个静态代码块之间按照顺序结构执行 * 4.静态代码块的执行要早于非静态代码块的执行 * 5.静态的代码块中,只能执行静态的结构(类属性,类方法) * 6.静态代码块初始化和显式赋值也是按照顺序结构执行 * ②非静态代码块(没有修饰): * 1.可以对属性(静态&非静态)进行初始化操作,同时也能调用方法(静态&非静态) * 2.可以写输出语句 * 3.一个类中可以有多个非静态代码块,多个代码块之间按照顺序结构执行 * 4.每创建一个类的对象,非静态代码块就加载一次 * 5.非静态代码块的执行要早于构造器 * 6.显式的初始化或静态代码块初始化按照顺序结构执行,下面的2和3 * * * 关于属性赋值的操作顺序:1.默认的初始化 (2.显式的初始化 3.非静态代码块 )4.构造器中初始化 * 5.通过方法对对象的属性进行修改 */public class TestOrder { public static void main(String[] args) { Order o1=new Order(); System.out.println(o1); System.out.println(); Order o2=new Order(1003,"BB"); System.out.println(o2); System.out.println(Order.orderDesc); }}class Order{ private int orderId=1001; private String orderName; //非静态初始化块 { orderId=1002; orderName="AA"; System.out.println("我是非静态代码块1!"); //orderDesc="(非静态代码块中)我是static的属性orderDes!"; } //private int orderId=1001; { System.out.println("我是非静态代码块2!"); } public Order() { super(); System.out.println("我是Order类的空参的构造器!"); } //静态代码块// static{// System.out.println("我是静态代码块2!");// } static{ orderDesc="(静态代码块中)我是static的属性orderDes!"; System.out.println("我是静态代码块1!"); } public static String orderDesc="(显式赋值)我是static的属性orderDes!"; public Order(int orderId,String orderName) { super(); this.orderId = orderId; this.orderName = orderName; System.out.println("我是Order类的不空参的构造器!"); } public int getOrderId() { return orderId; } public void setOrderId(int orderId) { this.orderId = orderId; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } @Override public String toString() { return "Order [orderId=" + orderId + ", orderName=" + orderName + "]"; } }
练习
package com.btp.t2;public class TestLesf { public static void main(String[] args) { new Leaf(); System.out.println(); new Leaf(); }}class Root{ static { System.out.println("Root的静态代码块!"); } { System.out.println("Root的普通代码块!"); } public Root() { System.out.println("Root的无参数构造器"); }}class Mid extends Root{ static { System.out.println("Mid的静态代码块!"); } { System.out.println("Mid的普通代码块!"); } public Mid() { System.out.println("Mid的无参数构造器"); } public Mid(String msg) { this(); System.out.println("Mid的带参数构造器,其参数值:"+msg); } }class Leaf extends Mid{ static { System.out.println("Leaf的静态代码块!"); } { System.out.println("Leaf的普通代码块!"); } public Leaf() { super("石头人"); System.out.println("执行Leaf的构造器!"); }}/*答案Root的静态代码块!Mid的静态代码块!Leaf的静态代码块!Root的普通代码块!Root的无参数构造器Mid的普通代码块!Mid的无参数构造器Mid的带参数构造器,其参数值:石头人Leaf的普通代码块!执行Leaf的构造器!Root的普通代码块!Root的无参数构造器Mid的普通代码块!Mid的无参数构造器Mid的带参数构造器,其参数值:石头人Leaf的普通代码块!执行Leaf的构造器! */
总结:
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
Static 静态:这里主要记录的是静态程序块和静态方法
如果有些代码必须在项目启动的时候就执行,就需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化但是不执行,在不创建对象的情况下,可以供其他程序调用,而在调用的时候才执行,这需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用。
静态代码块和静态方法的区别是:
静态代码块是自动执行的;
静态方法是被调用的时候才执行的.
静态方法:如果我们在程序编写的时候需要一个不实例化对象就可以调用的方法,我们就可以使用静态方法。