1. 程式人生 > >JAVA基礎之初始化與清理

JAVA基礎之初始化與清理

用構造器確保初始化

構造器與類名稱相同;是一種特殊型別的方法,因為它沒有返回值。
在建立物件時,會為物件分配儲存空間,並呼叫相應的構造器。
不包含任何引數的構造器叫做預設構造器

方法過載

class Person {
    public Person() {}
    public Person(String name){}
    public Person(String name,int age){}
}
  • 區分過載
每個方法都有獨一無二的引數型別列表
  • 方法過載
1.如果傳入的資料型別小於方法中宣告的形式引數型別,實際資料型別就會被提升;
 char略有不同,如果無法找到恰好接受char引數的方法,就會把char直接提升至int型
2.如果傳入的實際引數大於過載方法宣告的形式引數,就需要進行強制轉換,否則編譯器就會報錯。
eg:
void test(byte b) {}

int i = 5;
test(i);//編譯器會報錯

預設構造器

預設構造器又名“無參”構造器,是沒有形式引數的。
如果類中沒有構造器,編譯器會自動幫你建立一個預設構造器。
  • 作用
用於建立一個“預設物件”

this關鍵字

this關鍵字只能在方法內部使用,表示對“對呼叫方法的那個物件”的引用
如果在方法內部呼叫同一個類的另一個方法,就不必使用this,直接呼叫即可
class Test {
    private Test(){}
    public Test newInstance() {
        return this;
    }
}
  • 在構造器中呼叫構造器
class Test {
    String s;
    public Test(){this("test");}
    public Test(String s){this.s = s;}
}
構造器中只能用this呼叫一個構造器,並且必須置於初始處
除構造器外,編譯器禁止其他方法呼叫構造器
  • static的含義
可以通過類本身來呼叫static方法,也可以通過物件來呼叫
static方法就是沒有this的方法
在static方法內部不能呼叫非靜態方法,反過來是可以的。

清理:終結處理和垃圾回收

java垃圾回收器負責回收無用物件佔據的記憶體資源
垃圾回收器只知道釋放那些經由new分配的記憶體
  • finalize()的用途何在
一旦垃圾回收器準備好釋放物件佔用的儲存空間,將首先呼叫其finalize(),並且在下一次垃圾回收動作傳送時,才會真正回收物件佔用的記憶體
無論是“垃圾回收”還是“終結”,都不保證一定會發生。
如果java虛擬機器(JVM)並未面臨記憶體耗盡的情形,它是不會浪費時間去執行垃圾回收以恢復記憶體的。
System.gc()用於強制進行終結動作
Java虛擬機器採用一種自適應的垃圾回收技術。
  • 自適應技術
標記-清掃:
從堆疊和靜態儲存區出發,遍歷所有的引用,進而找出所有存活的物件。
每當它找到一個存活的物件,就會給物件設一個標記,這個過程中不會回收任何物件。
只有全部標記工作完成的時候,清理動作才會開始。
在清理過程中,沒有標記的物件將被釋放,不會發生任何複製動作。

停止-複製:
先暫停程式的執行,然後將所有的存活的物件從當前堆複製到另一個堆,沒有被複制的全部都是垃圾。

“標記-清掃”與“停止-複製”都是在程式暫停的情況下才能進行。

Java虛擬機器會進行監視,如果所有物件都很穩定,垃圾回收器的效率降低的話,就切換到“標記-清掃”方式;
同樣,Java虛擬機器會跟蹤“標記-清掃”效果,要是堆空間出現很多碎片,就會切換回“停止-複製”方式
  • 注意
1.物件可能不被垃圾回收
2.垃圾回收並不等於“析構”
3.垃圾回收只與內容有關

成員初始化

方法的區域性變數沒有初始化就會編譯出錯
  • 預設初始化
類的資料成員沒有初始化就會被賦予預設初始值

boolean:false
char:0(空白)
byte,short,int,long:0
float,double:0.0
物件:null
  • 指定初始化(自動初始化)
在定義類成員變數的地方為其賦值
class Test {
    int i = 10; //方式1
    int j = getNum(i); //方式2

    private int getNum(int i) {
        return i * 10;
    }
}

構造器初始化

在執行時刻,可以呼叫方法或執行某些動作來確定初值
無法阻止自動初始化的進行,它將在構造器被呼叫之前發生
  • 靜態資料的初始化
static關鍵字不能應用於區域性變數,無論建立多少個物件,靜態資料都只佔一份儲存區域
靜態初始化只有在必要時刻才會進行,靜態初始化只在Class物件首次載入的時候進行一次
  • 物件的建立過程

假設有個類為Dog

1.首次建立Dog物件(或Dog的靜態方法/靜態域首次被訪問)時,編譯器首先會找到Dog.class檔案
2.載入Dog.class,執行所有有關靜態初始化的動作
3.使用new Dog()建立物件時,首先在堆上為Dog物件分配足夠的儲存空間
4.這塊儲存空間會被清零,將Dog物件中所有基本型別資料設定成預設值(預設初始化),設定引用為null
5.執行所有出現與欄位定義處的初始化動作(指定初始化)
6.執行構造器
  • 初始化順序
變數定義的先後順序決定了初始化的順序,即使變數定義散佈於方法定義之間,它們仍舊會在任何方法(包括構造器)被呼叫之前得到初始化。
//當new Hello()時,物件建立順序依次為t1,t2,t3,t4,t5,t6
//靜態物件 - 靜態程式碼塊初始化 - 顯示初始化 - 構造程式碼塊初始化 - 建構函式初始化
class Test {
    public Test(int marker) {
        System.out.println("Test(" + marker + ")");
    }
}

class Hello {
    static Test t1 = new Test(1);
    Test t3 = new Test(3);
    Test t4;
    Test t5;

    static {
        //靜態程式碼塊,只執行1次
        Test t2 = new Test(2);
    }

    {
        //構造程式碼塊,先於構造器初始化,無論呼叫哪個建構函式,都會執行該初始化
        t4 = new Test(4);
    }

    public Hello() {
        t5 = new Test(5);
        Test t6 = new Test(6);
    }
}

陣列初始化

  • 定義陣列
型別後加[],如int[] i;或int i[];
  • 陣列初始化
int[] i = {1,2,3};
Integer[] a = new Integer[]{new Integer(1),2,new Integer(3)};
int[] j = new int[10];
Random rand = new Random();
int[] a = new int[rand.nextInt(20)];
Object[] obj = new Object[]{new Integer(1),new Float(2.0),new Double(3.0)};
Object[] objects = new Integer[]{1,2,3};
  • 可變引數列表
class Test {
    public static void main(String[] args) {
        Test test = new Test();
        test.printArray(1, new String("Hello"), new Float(2.0));
        test.printArray(2, (Object[])new String[] {"Hello","World"});
        test.printArray(0);
    }
    public void printArray(int num, Object... objects) {
        System.out.print(num + " ");
        for (Object object : objects) {
            System.out.print(object + " ");
        }
        System.out.println();
    }
}

列舉型別

由於列舉型別的例項是常量,按照命名慣例都用大寫字母表示
列舉型別可以在switch語句內使用
class Test {
    public enum Animal {
        PIG, DOG, SHEEP, DUCK, WOLF
    }
    public static void main(String[] args) {
        for (Animal animal : Animal.values()) {
            System.out.println(animal.ordinal() + " : " + animal);
        }
        Animal animal = Animal.PIG;
        System.out.print(animal);
    }
}