Java 編程思想 - 第二章 - 一切都是對象
儘管Java是基於C++的,但是相比之下,Java是一種更純粹”的面向對象程序設計語言。
用引用操縱對象
儘管一切都看作對象,但操縱的標識符實際上是對象的一個“引用”(reference)。
可以將這一情形相像成用遙控器(引用)來操縱電視機(對象)。
一個引用並不一定需要有一個對象與它關聯。
即使沒有電視機,遙控器亦可以獨立存在。
必須由你創建所有對象
存儲到什麼地方
程序運行時,對象是怎麼進行放置安排的呢?特別是內存是怎樣分配的呢?
- 寄存器。最快的存儲區,因爲它位於處理器內部。但寄存器的數量極其有限,所以寄存器根據需求進行分配。不能直接控制,也不能在程序中感覺到寄存器存在的任何跡象。
- 堆棧。位於通用RAM(隨機訪問存儲器)中,但通過堆棧指針可以從處理器那裏獲得直接支持。堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些內存。創建程序時,Java系統必須知道存儲在堆棧內所有項的確切生命週期,以便上下移動堆棧指針。某些Java數據存儲於堆棧中——特別是對象引用,但Java對並不存儲於其中。
堆。一種通用的內存池(也位於RAM區),用於存放所有的Java對象。編譯呂不需要知道存儲的數據在堆是存活多長時間。
new將對象存儲在“堆”裏。
常量存儲。常量值通常直接存放在程序代碼內部。
- 非RAM存儲。兩個基本的例子:流對象和持久化對象
特例:基本類型
基本類型 | 大小 | 最小值 | 最大值 | 包裝器類型 |
---|---|---|---|---|
boolean | – | – | – | Boolean |
char | 16-bit | Unicode o | Unicode | Character |
byte | 8 bits | -128 | +127 | Byte |
short | 16 bits | Short | ||
int | 32 bits | Integer | ||
float | 32 bits | IEEE754 | IEEE754 | Float |
double | 64 bits | IEEE754 | IEEE754 | Double |
void | – | – | – | Void |
- 所有數值類型都有正負號。
- boolean類型所佔存儲空間的大小沒有明確指定,僅定義爲能夠取字面值true或false。
- BigInteger支持任意精度的整數。
- BigDecimal支持任何精度的定點數。
Java中的數組
- 創建對象的數組時,實際上是創建了一個引用數組,每個引用都會自動被初始化爲null。
- 創建用來存放基本數據類型的數組時,將這種數組所佔的內存全部置零。
永遠不需要銷燬對象
作用域
在作用域裏定義的變量只可用於作用域結束之前。
對象的作用域
{
String s = "a string";
} //End of scope
引用s在作用域終點就消失了。然而,s指向的String對象仍繼續佔據內存空間。
由new創建的對象,只要需要就會一直保留下去。
Java有一個垃圾回收器,釋放不會再被引用的對象的內存空間。
static關鍵字
通常來說,當創建類時,就是在描述那個類的對象的外觀與行爲。除非用new創建那個類的對象,否則,實際上並未獲得任何對象。執行new來創建對象時,數據存儲空間才被分配,其方法才供外界調用。
有兩種情形用上述方法是無法解決的:
- 只想爲某特定域分配單一存儲空間,而不去考慮空間要創建多少對象,甚至根本就不創建任何對象。
- 希望某個方法不與包含它的類的任何對象關聯在一起。也就是說,即使沒有創建對象,也能夠調用這個方法。
通過static關鍵字可以滿足這一方面的需要。
class StaticTest {
static int i = 47;
}
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
在這裏,st1.i和st2.i指向同一存儲空間。
使用類名是引用static變量首選方式,類似邏輯也應用於靜態方法。
StaticTest.i++;
儘管當static作用於某個字段時,肯定會改變數據創建的方式(因爲一個static字段對每個類來說只有一份存儲空間,而非static字段則是對每個對象有一個存儲空間),但是如果static作用於某個方法,差別卻沒有那麼在。static方法的一個重要的用法就是在不創建任何對象的前提下就可以調用它。