java的學習:代碼塊

一、代碼塊的作用

在java,對於數據域的初始化除了通過構造器,以及聲明時賦值,還有就是使用代碼塊進行初始化賦值

二、代碼塊的分類

代碼塊分爲兩種,一種是被static關鍵字修飾的靜態代碼塊,一種是非靜態代碼塊

class Person{
    ...
    //非靜態代碼塊
    {
        System.out.println("這是非靜態代碼塊");
    }

	 //靜態代碼塊
    static {
        System.out.println("這是靜態代碼塊");
    }
    ...
}

在例子中,Person中直接以{ }括起來的沒有任何修飾的就是非靜態代碼塊。而以static關鍵字修飾的static{ }就是靜態代碼塊

2.1 非靜態代碼塊

public class PersonTest {
    public static void main(String[] args) {
        Person p=new Person("張三");
        System.out.println(p);
        System.out.println("==============");
        Person p2=new Person("李四");
        System.out.println(p2);
    }
}

class Person{
    private String name;
    private int age;
    private static String gender="未知";

    public Person(String name) {
        this.name = name;
    }

    //非靜態代碼塊
    {
        age=10;
        System.out.println("這是非靜態代碼塊1");
    }

    //非靜態代碼塊
    {
        System.out.println("這是非靜態代碼塊2");
        //調用靜態屬性
        gender="男";
        //執行非靜態方法
        walk();
        //執行靜態方法
        desc();
    }

    public void walk(){
        System.out.println("這是非靜態方法");
    }

    public static void desc(){
        System.out.println("這是靜態方法");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

運行結果:
在這裏插入圖片描述
通過上面的例子發現非靜態代碼塊:
作用:

  • 可以在創建對象時,對對象的屬性進行初始化

特點:

  • 隨着對象的創建而執行
  • 每創建一次對象時就執行一次非靜態代碼塊。
  • 如果類中定義了多個代碼塊,就按照類聲明中定義的次序來
  • 非靜態代碼塊內部可以有輸出語句

注意點:

  • 非靜態代碼塊內部可以調用靜態屬性,非靜態屬性,靜態方法,非靜態方法。

2.2 靜態代碼塊

public class PersonTest {
    public static void main(String[] args) {

        String desc=Person.desc;
        System.out.println("===============");
        System.out.println(desc);
        System.out.println("===============");
        Person.desc();
    }
}

class Person{
    private String name;
    private int age;
    private static String gender="未知";
    static String desc="這是個人";

    public Person(String name) {
        this.name = name;
    }

    static{
        System.out.println("這是靜態代碼塊1");
        //調用靜態方法
        desc();
        //調用非靜態方法
        //walk();//Non-static method 'walk()'cannot be referenced from a static context
    }

    static{
        System.out.println("這是靜態代碼塊2");
        //給靜態屬性賦值
        gender="男";
        desc="這是個男人";
        //給非靜態屬性賦值
        //age=10;//Non-static field 'age'cannot be referenced from a static context
    }

    public void walk(){
        System.out.println("這是非靜態方法");
    }

    public static void desc(){
        System.out.println("這是靜態方法");
    }
    
}

運行結果:
在這裏插入圖片描述

通過運行結果分析可以發現,在第一個分割符上方,是在通過類名.靜態屬性時(Person.desc)打印出來的,此時類就會加載到內存中,所以會執行靜態代碼塊中的代碼。而在運行結果的第二個分割符下的結果,是執行Person.desc()這個語句所打印出來的,因爲類此時已經加載過了,一個類只會加載一次,所以這時沒有再執行靜態代碼塊。

靜態代碼塊:
作用:

  • 可以對靜態屬性進行初始化

特點:

  • 隨着類的加載而加載,並且只執行一次
  • 如果定義了多個靜態代碼塊,按照順序依次執行
  • 靜態代碼塊在非靜態代碼塊之前執行
  • 內部可以執行輸出語句

注意點:

  • 靜態代碼塊只能調用靜態結構,不能調用非靜態結構

三、各種屬性賦值的先後順序

例如:

public class PersonTest {

    public static void main(String[] args) {

        Person p=new Person("張三");
    }
}

class Person{

    //非靜態代碼塊
    {
        System.out.println(this.id);
        System.out.println("這是非靜態代碼塊1");
    }

    //靜態代碼塊1
    static{
        System.out.println(Person.desc);
        desc="這是個人";
        System.out.println("這是靜態代碼塊1");
    }

    private int id=getValue();
    private String name;
    private int age;

    private static String gender;
    private static String desc=getDesc();

    //靜態代碼塊
    static{
        System.out.println("這是靜態代碼塊2");
    }


    public Person() {
        System.out.println("這是無參構造");
    }

    public Person(String name) {
        //調用無參構造
        this();
        System.out.println("這是有一個參數的構造");
        this.name = name;
    }

    //非靜態代碼塊
    {
        System.out.println("這是非靜態代碼塊2");
    }

    private int getValue() {
        System.out.println("這是非靜態屬性(實例域)顯式初始化");
        return 1;
    }

    private static String getDesc(){
        System.out.println("這是靜態屬性顯式初始化");
        return "兩個眼睛,一張嘴,兩條腿";
    }



}

運行結果:
在這裏插入圖片描述
通過運行結果和代碼的分析不難發現:

  1. 靜態屬性被初始化爲默認值
  2. 靜態屬性的顯式初始化和靜態代碼塊的執行順序,是按照類中定義的順序依次執行
  3. 非靜態屬性被初始化爲默認值
  4. 非靜態屬性的顯式初始化和非靜態代碼塊的執行順序,是按照在類中聲明的次序依次執行
  5. 構造器(如果構造器中第一行調用了其他構造器,則執行調用的構造器。如例子中一個參數的構造器,第一行通過this()調用了無參構造,則先執行無參構造,最後在執行一個參數的構造主體。)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章