原文出自 http://www.cnblogs.com/ggjucheng/archive/2012/11/28/2793158.html
對象
一個典型的java程式會建立很多個物件,就像你所知道的,這些對象通過方法調用進行互動。通過對象互動,程式可以完成很多任務,例如實現圖形介面運行動畫,通過網路發送或者接收資訊。一個建立好的對象,當它完成任務時,它的資源也會被其他對象重複使用。
這裡有一個小程式,叫CreateObjectDemo
,它建立三個對象:一個Point對象和兩個Rectangle
對象。編譯這個程式,我們需要三個源碼檔案。
public class CreateObjectDemo { public static void main(String[] args) { // Declare and create a point object // and two rectangle objects. Point originOne = new Point(23, 94); Rectangle rectOne = new Rectangle(originOne, 100, 200); Rectangle rectTwo = new Rectangle(50, 100); // display rectOne's width, // height, and area System.out.println("Width of rectOne: " + rectOne.width); System.out.println("Height of rectOne: " + rectOne.height); System.out.println("Area of rectOne: " + rectOne.getArea()); // set rectTwo's position rectTwo.origin = originOne; // display rectTwo's position System.out.println("X Position of rectTwo: " + rectTwo.origin.x); System.out.println("Y Position of rectTwo: " + rectTwo.origin.y); // move rectTwo and display // its new position rectTwo.move(40, 72); System.out.println("X Position of rectTwo: " + rectTwo.origin.x); System.out.println("Y Position of rectTwo: " + rectTwo.origin.y); }}
這個程式建立對象,操控對象,並顯示多個對象的資訊,這裡是輸出:
Width of rectOne: 100Height of rectOne: 200Area of rectOne: 20000X Position of rectTwo: 23Y Position of rectTwo: 94X Position of rectTwo: 40Y Position of rectTwo: 72
以下三個部分用上面的例子,在一個程式中來描述一個對象的生命週期。從中你將學會如何編寫代碼,在自己的程式中建立和使用對象。您還將瞭解當對象生命週期結束時,系統會清理對象。
建立對象
正如你所知道的,一個類會為對象提供藍圖,你可以使用類建立對象。CreateObjectDemo
程式每一個語句都是建立對象並賦值給變數:
Point originOne = new Point(23, 94);Rectangle rectOne = new Rectangle(originOne, 100, 200);Rectangle rectTwo = new Rectangle(50, 100);
第一行建立了Pointer類的對象,第二行和第三行分別建立了Rectangle
類的對象。 每一個語句都有三個部分(細節如下):
1.聲明:資料類型和變數名
2.執行個體化:new關鍵字是java操作符,用來建立對象。
3.初始化:new操作符緊跟著一個構造方法,用來初始化對象。
聲明一個指向對象的變數
之前,我們學到,聲明一個變數,會這麼寫:
type name;
這個通知編譯器,你將會使用name指向類型為type的資料。如果是原生類型的變數,這個聲明會為變數分配合適大小的記憶體。
你也可以在單行聲明一個引用變數,例如:
Point originOne;
如果這麼聲明originOne,它的值在建立一個對象並賦值給它之前,是不確定的。聲明一個引用變數不會建立一個對象。建立對象,需要使用new操作符。我們必須在代碼中使用originOne
之前,必須賦值一個對象給它。否則,編譯器會報錯。
一個變數如果在沒有指向任何對象的狀態下,可以詳解如下(變數名,originOne, 加一個沒有指向其他對象的引用):
執行個體化一個類
new操作符執行個體化類的對象,分配記憶體,返回記憶體的引用。new操作符也調用類的構造方法。
注意:執行個體化類意味著建立一個對象,當你建立一個對象是,你就是建立了一個類的執行個體,這就是執行個體化一個類。
new操作符要求一個獨立,尾碼的參數:一個構造方法的調用,構造方法的名字提供對應類的執行個體化。
new操作符返回建立的對象引用,這個引用用於賦值給合適類型的變數,例如:
Point originOne = new Point(23, 94);
new操作符返回的引用未必一定要賦值給一個變數,它也可以直接在運算式使用。例如:
int height = new Rectangle().height;
初始化對象
這裡是Point類的代碼:
public class Point { public int x = 0; public int y = 0; //constructor public Point(int a, int b) { x = a; y = b; }}
這個類只有一個構造方法。你可以看出它是一個構造方法,因為它的聲明使用的名字和類名一樣,而且沒有傳回值。Point類的構造方法有兩個整形參數,就像代碼的聲明 (int a, int b)。跟著的語句使用23和94作為參數的值:
Point originOne = new Point(23, 94);
語句的執行結果,可以以來詳解:
這裡是Rectangle類的代碼,它有四個構造方法:
public class Rectangle { public int width = 0; public int height = 0; public Point origin; // four constructors public Rectangle() { origin = new Point(0, 0); } public Rectangle(Point p) { origin = p; } public Rectangle(int w, int h) { origin = new Point(0, 0); width = w; height = h; } public Rectangle(Point p, int w, int h) { origin = p; width = w; height = h; } // a method for moving the rectangle public void move(int x, int y) { origin.x = x; origin.y = y; } // a method for computing the area // of the rectangle public int getArea() { return width * height; }}
每個構造方法都會讓你提供長方形的長度和寬度的初始值,參數是原生類型和參考型別都有。如果一個類有多少構造方法,他們必須有不同的簽名。java編譯器通過參數的個數和類型,區別構造方法。當java編譯器遇到下面的代碼,它知道要調用參數為Pointer並緊跟兩個整數的Pointer類的構造方法:
Rectangle rectOne = new Rectangle(originOne, 100, 200);
這個構造方法的調用,初始化rectOne 為originOne
。同樣的,構造方法會把寬度設定為100,高度設定為200.現在這裡有兩個引用指向同一個Point對象----一個對象可以被多個引用指向,就像顯示:
下面的代碼調用Rectangle類參數為兩個整數類型的構造方法,它會提供width和height的初始化值。如果檢查構造方法的代碼,你會看到裡面會建立一個Point對象,屬性x和y初始化為0:
Rectangle rectTwo = new Rectangle(50, 100);
下面的語句,Rectanglez構造方法沒有任何參數,它稱之為無參構造方法:
Rectangle rect = new Rectangle();
所有類至少有一個構造方法,如果類沒有顯式聲明一個構造方法,java編譯器會自動提供一個構造方法,稱之為預設構造方法。預設構造方法調用父類的無參構造方法。如果父類沒有構造法方法(Object類有一個構造方法),編譯器會拒絕這個程式。
使用對象
當你建立對象後,你極有可能用它來做一些事情,你可能使用它的成員變數的值,改變它的成員變數的值,或者是調用它的方法完成某個任務。
引用對象的成員變數
對象成員變數是通過名字訪問的,你必須使用一個明確的名字。
你可以在類裡使用一個簡單的名字。例如,我們可以在Rectangle
類添加一個語句,輸出長度和高度:
System.out.println("Width and height are: " + width + ", " + height);
這個情境下,width
和height就是簡單的名字。
在代碼中,在類以外訪問必須使用類的引用或者運算式,緊著一個.操作符,緊著一個簡單的成員變數名,例如:
objectReference.fieldName
例子,CreateObjectDemo類的代碼,是在Rectangle的外層,所以要引用對象名為rectOne的origin, width, and height這些成員變數,CreateObjectDemo類必須分別使用rectOne.origin, rectOne.width,rectOne.height.這個程式使用下面的名字顯示rectOne對象的寬度和高度:
System.out.println("Width of rectOne: " + rectOne.width);System.out.println("Height of rectOne: " + rectOne.height);
的在CreateObjectDemo類中的代碼嘗試使用簡單的名稱width 和height是沒有任何意義 - 這些成員變數只存在對應的對象,這會導致 一個編譯錯誤。
等下這個程式會使用相同的代碼,顯示rectTwo的資訊。同一類型的多個對象,本身都有自己成員變數的拷貝。所以每一個Rectangle對象都有自己的成員變數origin, width, height.當你通過對象引用訪問執行個體的成員變數時,你引用的就是對應的對象的成員變數了。兩個對象rectOne 和rectTwo在CreateObjectDemo程式中都有自己的origin, width, height成員變數。
為了訪問成員變數,你可以使用一個對象的命令引用,就像之前的例子,或者使用一個運算式返回一個對象引用。重新調用new操作符返回一個對象的引用。回想一下,new操作符會返回一個對象引用。所以你可以new返回的值,訪問對象的成員變數:
int height = new Rectangle().height;
這個語句建立了Rectangle對象並理解擷取它的高度。在本質上,這個語句擷取了一個Rectangle的預設高度,但是這個語句執行後,這個程式沒有任何 引用指向了建立的Rectangle對象。因為程式沒有儲存該引用。對象沒有被引用,它的資源會被java虛擬機器回收。
調用對象的方法
你可以通過對象引用調用對象的方法。你在對象引用添加.操作符,再追加方法的簡明名字。當然,你需要在閉合的小括弧內提供方法的參數。如果方法不要求任何參數,使用空的小括弧。
objectReference.methodName(argumentList);or:objectReference.methodName();
Rectangle類有兩個方法:getArea()計算長方形的面積,move()修改長方形的大小,CreateObjectDemo代碼調用了以下兩個方法:
System.out.println("Area of rectOne: " + rectOne.getArea());...rectTwo.move(40, 72);
第一個語句調用rectOne的getArea()方法,並顯示結果。第二個語句調整rectTwo的大小,move()方法將對象的origin.x和origin.y重新賦新值。
和執行個體成員變數一樣,objectReference必須是一個對象引用。您可以使用一個變數的名字,但你也可以使用任何返回一個對象引用的運算式。new操作符返回一個對象的引用,這樣你就可以使用new的傳回值調用新對象的方法:
new Rectangle(100, 50).getArea()
運算式new Rectangle(100, 50)返回一個對象引用,它指向了Rectangle對象。,你可以使用.符號來調用新的Rectangle的getArea()方法計算新建立的長方形形的面積。
一些方法,如getArea(), 返回一個值。針對方法的傳回值,你可以在運算式中使用方法調用,把傳回值賦值給變數,使用它來做條件判斷,迴圈控制。下面的代碼,把getArea()的傳回值賦值給變數areaOfRectangle:
int areaOfRectangle = new Rectangle(100, 50).getArea();
記住,對一個對象調用方法,就像給對象發送訊息。這個情境下,構造方法返回的rectangle對象引用並調用getArea()
記憶體回收行程
一些物件導向的語言需要你跟蹤建立的所有對象,當他們不需要時,您要顯式地銷毀他們時。顯示管理記憶體是繁瑣並容易出錯的, Java平台允許您建立儘可能多的想要的對象(數量有限由你的系統的處理能力決定),你不必擔心什麼時候銷毀對象。 Java運行時中刪除不再被使用的對象,這個過程被稱為“記憶體回收。
當對象沒有任何引用時,它就符合垃圾收集器的回收對象了。引用一般儲存在變數裡,當變數離開了代碼塊的範圍,就會銷毀了。當然,你也可以把一個變數設定為null,顯式刪除一個對象引用。注意的是程式中,一個對象可以有多少引用,所有的引用刪除了,這個對象才符合垃圾收集器的回收對象。
Java運行時環境有一個垃圾收集器,周期性地釋放不再被引用的對象的記憶體。垃圾收集器會自動運行,由它本身決定啟動並執行正確時間。