【Java】構造方法和匿名對象


前言

在編寫程序時不安全的初始化會導致程序發生發生重大錯誤。為了使程序可以被安全地初始化,C++引入了構造器(也可以成為構造方法)的概念,這是一個在創建對象時被自動調用的特殊方法。Java中也采用了構造器,並且提供了“垃圾回收器”。對不再使用的內存資源,垃圾回收器能自動將其釋放。本文下面主要介紹Java的構造方法以及匿名對象。

構造方法的定義語法與調用時機

構造方法的定義語法及訪問權限

構造方法是在創建對象時被編譯器自動調用,所以編譯器應該知道構造方法的名字然后去調用它,為構造方法任意取名都可能會與類的某個成員沖突。於是Java采用了同C++中一樣的方法:構造方法采用與類相同的名稱

構造方法一般定義為如下三種方式:

class Student{
  public Student(){     //①
    ...
  }
  ...
}
class Student{
  Student(){      //②
    ...
  }
  ...
}
class Student{
  private Student(){    //③
    ...
  }
  ...
}

以上三種構造方式涉及到了訪問權限的問題:

第①種方式,構造方法采用了public修飾表示該類的對象是可以被不同包(package)的其他類創建。

第②種方式,默認為包訪問屬性,僅限於同包的類可以創建該類的對象。

第③種方式,使用private修飾使得構造方法對外不可見,無法在外部調用該類的構造器創建其實例。一般通過工廠模式創建該類實例。

以上列舉了三種訪問權限訪問修飾符,如果學過C++那舊還知道一種沒有出現的訪問權限修飾符就是protected。該修飾符表示本包中的類可訪問,不同包中的子類可以訪問。

對包做一個解釋:包類似於電腦中的文件夾,文件多了需要存於不同文件夾中方便管理,同樣如此,類多了就需要放在不同的包里面方便管理,同時也避免了命名沖突問題。

總結訪問權限修飾符的可訪問性:

范圍 private default(默認包訪問) protected public
同一個類 O O O O
同一個包中的子類 X O O O
同一個包中的其他類 X O O O
不同包中的子類 X X O O
不同包中的非子類 X X X O

構造方法的調用時機(創建對象的初始化順序)

前面一直在說構造方法的調用是在類創建時,與普通方法不同,構造方法在實例化新對象(使用new開辟空間后)調用一次。普通方法在對象被實例化后可以調用多次。

由於對初始化有不同的需求,因此構造方法也可重載的。

下面跟蹤一下構造方法被調用的過程:

class Person{
	  private long pid=123456789;
	  public Person(){
		  System.out.println("Person()");
	  }
	  public Person(long pid){
		System.out.println("Person(long pid)");
		System.out.println("在使用傳進來的pid賦值前:pid:"+this.pid);
	    this.pid = pid;
	    System.out.println("在使用傳進來的pid賦值后:pid:"+this.pid);
	  }
}
public class Student extends Person{   //extends 實現繼承關系
  private String name;
  private int age=0;
  public Student(){
	  System.out.println("Student()");
  }
  public Student(long pid, String name, int age){
    super(pid);			//調用父類的構造函數一定要寫在最前面不然會報錯
    System.out.println("Student(long pid, String name, int age)");
    this.name = name;
    this.age = age;
  }
  public getName(){
    return name;
  }
  public static void main(String[] args){
    Student stu1 = new Student();
    Student stu2 = new Student(123456,"Sakura",20);
  }
}
/*
output:
Person()
Student()
Person(long pid)
在使用傳進來的pid賦值前:pid:123456789
在使用傳進來的pid賦值后:pid:123456
Student(long pid, String name, int age)
*/

可以輸出結果看出Java中的初始化順序如下:

  • 在任何其他事情發生之前,首先會將分配給對象的存儲空間初始化成二進制零。
  • 調用基類的構造函數。
  • 按照聲明順序調用屬性的初始化方法。在Person中先將pid賦值為1234556789然后在返回到構造函數中將123456賦值給pid。
  • 調用導出類的構造函數。若是Student中屬性有給定初始值,那么依舊如第三步后再進入構造函數進行其他初始化操作。

匿名對象

什么是匿名對象?

我們來看一步就創建對象的語法:

①類名稱 ②對象名稱 = ③new ④類名稱()
  1. ①:規定了對象的類型
  2. ②:對象的名字,唯一標識對象
  3. ③:開辟新的堆內存空間,存儲對象的內容
  4. ④:調用構造方法初始化對象

上面的這條語句在內存中開辟了兩個空間,一個棧空間存儲引用變量對象名稱,一個使用new開辟的堆空間用於存儲對象內容。

對象名稱指向了在對堆中的對象,於是我們可以使用對象名稱去操作對象

若是我們只有"new 類名稱();"這部分的話,那就是只是在堆中開辟了一個空間來保存對象信息,沒有棧去指向它。也就是這個空間是沒有名字的。所以簡單來說,沒有棧中引用指向的對象就叫做匿名對象

匿名對象的使用

new Student(123456,"Sakura",20).getName();

由此就創建了一個匿名對象,可以向操作具名對象一樣操作它。
由於沒有引用變量指向匿名對象,所以只能使用一次,然后就會成為垃圾對象等待被GC回收,

小結

總結了Java中構造方法的定義和作用(為了在類對象實例化時設置屬性初始化)由此涉及到到類訪問權限,然后對類訪問權限做了一個小結,以及Java程序初始化的順序。最后介紹了匿名對象,即沒有棧中引用指向的對象。

參考:

[1] Eckel B. Java編程思想(第四版)[M]. 北京: 機械工業出版社, 2007


免責聲明!

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



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