第2章 一切都是對象
儘管Java是基於C++的,但是相比之下,Java是一種更“純粹”的面向對象程序設計語言。Java語言假設我們只進行面向對象的程序設計。也就是說,在開始用Java進行設計之前,必須將思想轉換到面向對象的世界中來。
2.1 用引用操作對象
每一種編程語言都有自己操縱內存中元素的方式。在Java中,一切都是對象,因此可以採用單一固定的用法。儘管在Java中一切都是對象,但是操作的標識符實際上是對象的一個引用。就像遙控器(引用)遙控電視(對象)一樣。而且可以只有引用,而沒有與該引用關聯的對象。就像可以只有遙控器,沒有電視。
String s;//只有引用,容易出現問題
String s = “abc”;//安全做法:創建引用時初始化
2.2 必須由你自己創建對象
一旦創建了一個引用,就希望它能與一個對象關聯。可以使用new操作符實現該想法。
String s = new String(“abc”);
那這些對象存儲到什麼地方呢?
A.寄存器:位於CPU內部,速度最快,數量有限。
B.堆棧:位於通用RAM中。若堆棧指針下移,則分配新內存;若上移,則釋放內存空間。這樣方式僅次於寄存器。
C.堆:一個通用的內存池(RAM中),用於存放所有的Java對象。堆不同於堆棧的好處是:編譯器不需要知道存儲在堆中的對象存活多久。這樣很靈活,但是用堆存儲分配和清理的時間比堆棧多。
D.常量存儲:直接存放在代碼內部,這樣很安全,保證永遠不會被修改。
E.非RAM存儲:如果數據完全存活於程序之外,那麼它肯定不受程序控制。如持久化對象。
對於基本類型來說,Java採取和C/C++相同的方法,不用new來創建變量,而是創建一個並非是引用的“自動”變量。這個變量直接存儲“值”並且將其置於堆棧中。
Java中的基本數據類型所佔用存儲空間是固定,這樣佔用的存儲空間大小不會隨着硬件架構的改變而改變,這樣提高Java的可移植性。基本類型如下:
基本類型 |
大小 |
最小值 |
最大值 |
默認值 |
包裝器類型 |
boolean |
- |
- |
- |
false |
Boolean |
char |
16b |
Unicode0 |
Unicode2^16-1 |
\u0000 (null) |
Character |
byte |
8b |
|
|
(byte)0 |
Byte |
short |
16b |
-2^15 |
+2^15-1 |
(short)0 |
Short |
int |
32b |
|
|
0 |
Integer |
long |
64b |
|
|
0L |
Long |
float |
32b |
|
|
0.0f |
Float |
double |
64b |
|
|
0.0d |
Double |
void |
- |
- |
- |
- |
Void |
說明:
A.所有數值類型都是有符號數。
B.boolean類型所佔存儲空間沒有指定,僅能取值ture和false。
C.基本數據類型具有包裝器類,使得可以在堆中創建一個非基本數據類型的對象,用來表示對於的基本數據類型。
D.Java中提供了2個高精度計算的類:BingInteger(支持任意精度的整數)和BigDecimal(支持任意精度的定點數)。
在Java中會確保數組被初始化,而且不會在它的範圍之外被訪問。這樣範圍檢查,是以每個數組上少量的內存開銷和運行時的下標檢查作爲代價的。
當創建一個數組時,實際上就是創建了一個引用數組,並且每個引用都會自動被初始化爲特定值,該值就是null。一旦Java看到null,就知道這個引用還有與對象關聯。
2.3 永遠不需要銷燬對象
在程序設計語言中要考慮對象的作用域問題。也就是說要了解對象的生命週期。先看下基本數據類型的作用域:
{
int x = 10;//只有x
{
int y = 20;//有x和y
}
//只有x
}
Java對象的作用域與基本數據類型的作用域不同。當用new創建一個對象後,它可以存活在作用域之外。
{
String s = “abc”;
}//引用在這裏就結束了
但是,s指向的String對象仍然在堆空間中。
2.4 創建新的數據類型:類
在Java中,一切都是對象。但是我們需要一種能夠表示對象的外觀和行爲的一種類型。所以引入了一個新的基本類型-類。
一旦定義了類(事實上,程序員所做的工作就是創建類,然後生成這個類的對象以及發送消息給這個對象),就需要在類中設置兩種類型的元素:字段(數據成員)和方法(成員函數)。
字段可以是基本數據類型,也可以是對象的引用。
方法決定了一個對象能夠接受什麼樣的消息。方法包括方法名、參數、返回值和方法體。方法名和參數列表(合起來成爲“方法簽名”)唯一的標識出某個方法。Java中的方法只能作爲類的一部分來創建。方法只能通過對象來調用(static方法除外)。
int x = a.f();//發送消息f給對象a
方法的參數列表指定要傳遞給參數什麼樣的信息。在參數列表中必須指定每個傳遞對象的類型和名字。像Java中任何傳遞對象的場合一樣,這裏實際上傳遞的對象的引用,並且引用的類型必須正確。
int storage(String s)
{
return s.length()*2;
}
關於return關鍵字的用法有二:
A.它說表已經做完,離開此方法
B.返回一個值
若返回值爲void,則return關鍵字的作用就只退出當前方法。
2.6 構建一個Java程序
首先考慮到命名爲問題?如果使得命名不會衝突?Java中使用命名空間解決該問題。將域名反轉作爲包名即可。
如果引用其他類?Java中使用import關鍵字引入其他類。
通常來說,當我們創建類時,就是爲了描述對象的外觀和行爲。使用new關鍵字就可以得到一個新的對象。而有兩種情況是用new不能解決的:
A.想爲特定域分配單一的存儲空間,而不考慮創建多少個對象,甚至不創建對象。
B.希望某個方法不與它的類的任何對象關聯。
使用static關鍵字就可以滿足上述需求。static關鍵字可以放在字段(稱爲類數據)和方法(稱爲類方法)前,表面它們不與類中的任何對象關聯。Static方法的一個重要用法就是在不創建任何對象的情況下調用該static方法。如:
Class Test{
static int i = 47;
}
Test test1 = new Test();
Test test2 = new Test();
則test1.i和test2.i指向同一存儲空間,都是47。
2.7 你的第一個Java程序
編譯:javac Test.java
運行:java Test
2.8 註釋和嵌入式文檔(沒看完)
Java中有兩種註釋風格:A.多行註釋/* 註釋內容 */。B.單行註釋//註釋內容。如:
/*
*註釋內容,注意:進行編譯時/*和*/之間的*都會忽略。
*/
//這就是單行註釋
代碼與文檔如果分離則難以對文檔維護。所以Java可以將代碼和文檔鏈接在一起。最簡單的方法就是將代碼和文檔放在一個文件中。因此,Java中使用一種特殊的註釋語法來標記文檔,此外還需要一個工具來提取這些註釋。
Javadoc便是用來提取文檔的工具。它採用java編譯器的某些技術,查找程序內的特殊註釋標籤。它不僅解析由這些標籤標記的信息,而且還將毗鄰的類名或方法名提取出來。最終生成一個html文件。
2.9編碼風格
Java中採用“駝峯風格”。規定是這樣的:類名首字母大寫;如果類名中包含多個單詞,則把它們並在一起,每個單詞首字母大寫。方法、字段、對象引用名稱的規定與類的基本一致,只是首字母小寫而已。