java 初始化


初始化

這里的主要內容是 初始化相關的內容,其中還會穿插其他的內容

  1. 構造器初始化
  2. 靜態數據初始化
  3. 顯示的靜態初始化
  4. 非靜態實例初始化

穿插內容

  1. 構造器
  2. 方法重載
  3. this關鍵字
  4. static 關鍵字

構造器初始化

構造器

​ 構造器是在創建對象時被調用的特殊方法。(構造器是一個方法只不過它是特殊的),之所以特殊是因為構造器沒有返回值。與返回空(void)不同。一個簡單的說法,普通方法就算是void,還是可以掉的,但構造器沒得改。構造器是一個靜態的方法,

​ 構造器中的方法名與它所在的類名相同。這是因為為了讓編譯器能夠知道該調用那個方法。在創建對象時,編譯器將為對象分配存儲空間,並調用相應的構造器,這保證了你在操作對象之前,恰當的初始化了。

public class Apple {
    // 默認構造器
    Apple(){
        System.out.println("Hello Word");
    }
}

class Test{
    public static void main(String[] args){
        Apple apple = new Apple();
    }
}

​ 沒有參數出入的構造器叫默認構造器,術語是無參構造器,有參數的叫有參構造器。

public class Apple {
    //有參構造器
    Apple(String a){
        System.out.println(a);
    }
}

class Test{
    public static void main(String[] args){
        Apple apple = new Apple("Hello Word");
    }
}

​ 如果 Apple(String) 是類里唯一一個構造器,那么你在創建對象時必須傳入參數。

注意:在java中初始與創建是捆綁在一起的,二者不能分離

​ 默認構造器在沒有其它的構造器時,編譯器會自動創建一個默認構造器,如果類中有了構造器(無論是否有參數),編譯器就不會自動創建了。如果沒有構造器,就無法創建對象。

​ 像下邊這么寫就會編譯器會報錯,因為 編譯器沒有找到 new Apple(); 沒有參數的構造器

public class Apple {
    Apple(String a){
        System.out.println(a);
    }

    public void t(){
        return;
    }
}

class Test{
    public static void main(String[] args){
        Apple apple = new Apple();
    }
}

像下邊加一個無參構造器即可。

public class Apple {
    Apple(){
        System.out.println("Hello Word");
    }
    Apple(String a){
        System.out.println(a);
    }

    public void t(){
        return;
    }
}

class Test{
    public static void main(String[] args){
        Apple apple = new Apple();
    }
}

​ 在上邊的 Apple 類中,兩個構造器它們名字相同,傳入的參數不同,這種寫法叫 方法重載,在普通方法中也同樣適用

方法重載

​ 方法重載就好比相同的詞可以表達不同的含義,重載方法名字要相同其中一個重要原因是因為構造器,的名字要與類名相同,這樣只有一個構造器名,就可用多種方式創建一個對象。普通方法的重載也和構造器一樣。

public class Apple {
    /*   重載構造器   */
    Apple(){
        
    }
    
    Apple(String name){
        
    }
    
    Apple(String name, Integer num){
        
    }
    
    Apple(Integer num, String name){
        
    }
    
    

    /*   重載的方法  */

    /**
     * 獲取蘋果
     */
    public void getApple(){
        
    }

    /**
     * 獲取特定品種的蘋果
     * @param type 品種
     */
    public void getApple(String type){
        
    }

    /**
     * 獲取特定品種,即某一數量的蘋果
     * @param type 蘋果品種
     * @param num 蘋果數量
     */
    public void getApple(String type, Integer num){
        
    }

    /**
     * 獲取特定品種,即某一數量的蘋果
     * @param num 蘋果品種
     * @param type 蘋果數量
     */
    public void getApple(Integer num, String type){
        
    }
    
}

​ java區分方法名相同的方法,是根據每個方法的獨一無二的參數列表去區分的。

​ 如下這種情況雖然java允許 ,也最好不要用,因為會使得程序難以維護

    
    Apple(String name, Integer num){
        
    }
    
    Apple(Integer num, String name){
        
    }
	
	/**
     * 獲取特定品種,即某一數量的蘋果
     * @param type 蘋果品種
     * @param num 蘋果數量
     */
    public void getApple(String type, Integer num){
        
    }

    /**
     * 獲取特定品種,即某一數量的蘋果
     * @param num 蘋果品種
     * @param type 蘋果數量
     */
    public void getApple(Integer num, String type){
        
    }
    

拓展:java為什么不用返回區重載方法。

​ 有的時候並不需要一個方法返回東西,只需要方法本身的作用。

    public void test(){
        a();
    }
    public void test(String name){
        b(name);
    }

this 關鍵字

​ this關鍵字只能在方法內部使用,表示“調用方法的那個對象”。比如在Apple類的后一個方法中使用了this,this代表的就是Apple類。

public class Apple {


    public void getApple(){

    }

    public void juice(){
        this.getApple();
    }
}

注意:在上邊的 juice() 方法中有調用,同一個類中的方法 getApple() ,在這里是沒有必要加 this的,因為編譯器會自動幫忙加上。雖然手動加也可以,不過高級語言之所以高級,其中一個原因就是它可以幫助我們省略一些重復的事情。

​ 只用當需要指明當前對象時才需要使用 this

public class AppleNum {

    private int appleNum = 0;

    public AppleNum sumAppleNum(){
        appleNum ++;
        return this;
    }

    public void print(){
        System.out.println("總和:" + appleNum);
    }

    public static void main(String[] args) {
        AppleNum appleNum = new AppleNum();
        appleNum.sumAppleNum().sumAppleNum().sumAppleNum().print();
    }

}

​ 如上代碼 sumAppleNum() 方法返回的 appleNum 對象的引用,從而使得可以循環調用 sumAppleNum() 方法。

​ this 可以有參數列表用於構造器調用構造器,構造器不能使用方法名調用構造器,也不能在普通方法普通方法中。在同一個構造其中 this只能調用一個構造器。

    AppleNum(){
        this("a");
        
    }
    AppleNum(String type){
        this(3);
    }
    AppleNum(Integer i){

    }


    public AppleNum sumAppleNum(){
        // this(3)  編譯器會報錯
    }

成員初始化

​ 如果類中的基本類型字段沒有初始化,那java會為他們賦上默認值

public class Apple {

    boolean t ;
    char c;
    byte b;
    short s;
    int i;
    long l;
    float f;
    double d;
    Apple apple;

    public void get(){
        System.out.println(t);
        System.out.println(c);
        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(l);
        System.out.println(f);
        System.out.println(d);
        System.out.println(apple);
    }

    public static void main(String[] args) {
        Apple apple = new Apple();
        apple.get();
    }

}

從上邊代碼可以看出,基本類型變量沒賦值,java會默認賦上初始值。對象賦上 null,初始化的順序,影響着程序的正確性。

靜態數據初始化

​ 除非用 new 創建對象,否則實際上並未獲得任何對象。如果不想創建對象也能調用某一方法或屬性,就可以使用static 關鍵字。當聲明一個事物是 static 時,就意味着這個域或方法不會它所在的類的對象實例關聯在一起。

static關鍵字

加上了 static關鍵字,即為靜態成員變量。

public class Apple {
    
    static int i = 1;
    
    public static void get(){
        
    }

    public static void main(String[] args) {
        Apple.get();
        int num = Apple.i;
    }

}

上邊展示了 static 關鍵字的基本用法,不用 new 對象也可以調用方法,雖然不用創建對象也可以調用方法,並不是說每個方法都加上 static, 如果你的代碼是這樣,那你就得考慮一些你代碼的設計問題了。

​ 下邊是加了 static,與沒加 static 的區別

public class Apple {

    static int i = 1;
    int b = 2;

    public void get() {
        System.out.println(i);
        System.out.println(b);
    }

    public void  set(int b){
        // 這里因為入參的名字,與字段名相同 一般使用 this 將其區分
        this.b = b;
    }

    public static void main(String[] args) {
        Apple a = new Apple();
        Apple b = new Apple();
        a.get();
        b.get();

        /*====*/
        System.out.println(" /*====*/ ");
        Apple.i = 10;
        b.set(3);
        a.set(4);

        a.get();
        b.get();
    }
}

通過上邊的輸出返現 , a b 兩個對象在輸出 i 時是相同的,a.i b.i指向了同一個內存地址。這也說明多了無論創建多少對象,靜態數據都只占一份存儲區域。

​ 靜態初始化只有在必要時刻才會進行,例如,如果創建 Apple 對象 或者 不調用 Apple.i 那靜態的 i 永遠不會被創建出來。

​ 關鍵字 this 不可以在靜態方法中使用。關鍵字 this 代表的是對象的引用,而靜態方法不依賴於類的具體對象。

顯示的靜態初始化

多個靜態初始化,可以簡化成一個靜態塊

public class Apple {
    static {
        int i;
        char a;
        Apple c= new Apple()
    }
}

上邊這么寫,因為是在大括號里,意味着是局部變量除非將對象返回出去,否則外邊的方法,里邊的屬性

public class Apple {
    Apple c;
    static {
        c = new Apple();
    }
}

非靜態實例初始化

非靜態實例初始化,看起來和靜態塊非常像,區別就是沒有 static 關鍵字

public class Apple {
    Apple c;
    {
        int i;
        char a;
        c = new Apple();
    }
}

這個寫法的非靜態初始化主要是為了匿名內部類准備的。這保證了不管調用那個構造器這部分代碼都會被自行

public class Apple {
    Apple(){
        System.out.println("5");
    }

    {
        System.out.println("2");
    }
    static {
        System.out.println("1");
    }

    {
        System.out.println("4");
    }

    {
        System.out.println("3");
    }


    public static void main(String[] args) {
        Apple apple = new Apple();
    }
}

從上邊的代碼運行輸出可以看出,靜態塊先被執行,然后是非靜態塊,最后是,構造器

​ 靜態初始化塊只在類第一次被加載時執行,非靜態初始化塊在每次創建對象時執行一次,因此創建了多少個對象,就會執行多少次非靜態初始化塊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM