java編程思想 第二章
這篇時間較之前篇章時間靠後,是由於,某一天晚上看完Java編程思想文獻之後來不及做筆記了。
以下筆記基本為轉載,不是原創
第二章 一切都是對象
目錄:
- 2.1 用引用操縱對象
- 2.2 必須由你創建所有對象
- 2.3 永遠不需要銷毀對象
- 2.4 創建新的數據類型:類
- 2.5 方法、參數和返回值
- 2.6 構建一個Java程序
- 2.7 你的第一個Java程序
- 2.8 註釋和嵌入式文檔
- 2.9 編碼風格
2.1 用引用操縱對象
一切都看作對象,操縱的標識符實際上是對象的一個“引用”,遙控器(引用)操縱電視機(對象),想調控電視,只需通過遙控器,且遙控器是獨立存在的。
2.2 必須由你創建所有對象
一旦創建了一個引用,就希望它能與一個新的對象相關聯,通常用new操作符來實現這一目的。
String s = new String("Jiancheng");
存儲數據的五個地方:
1)寄存器。這是最快的存儲區,因為它位於不同於其他存儲區的地方——處理器內部。
2)堆棧。位於通用RAM(隨機訪問存儲器)中,但通過堆棧指針可以從處理器那裏獲得直接支持。
堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些內存。這是一種快速有效的分配存儲方法,僅次於寄存器。
創建程序時,Java程序必須知道存儲在堆棧內所有項的確切生命周期,以便上下移動堆棧指針。
3)堆。一種通用的內存池也位於RAM區,用於存放所有的Java對象。
堆不同於堆棧的好處是:編譯器不需要知道存儲的數據在堆裏存活多久時間。
當需要一個對象時,只需用new寫一行簡單的代碼。
用堆進行存儲分配和清理可能要比用堆棧進行存儲分配需要更多的時間。
4)常量存儲。常量通常直接存放在程序代碼內部,這樣做是安全的,因為它們永遠不會被改變。
在嵌入式系統中,常量本身會和其他部分隔離開,所有這種情況下,可以選擇將其存放在ROM(只讀存儲器)中。
5)非RAM存儲。如果數據完全存活於程序之外,那麽它就不受程序的任何控制,在程序沒有運行是也可以存在。
其中兩個基本例子是流對象和持久化對象。
在流對象中,對象轉化成字節流,通常被發送給另一臺機器。
在“持久化對象”中,對象被存放於磁盤上,因此,即使程序終止,它們仍可以保持自己的狀態。
堆棧是棧。(重要的事情說三遍,這是第二遍)
堆棧指針若向下移動,則分配新的內存;若向上移動,則釋放那些內存。這句話之前一直都不理解,因為大學學習的數據結構中,棧底就是在底部,棧頂就是在頂部,所以堆棧指針向下移動的話,應該是釋放內存的,所以這句話錯了?當然不是!
linux中一個進程的虛擬內存分布:
圖中0號地址在最下邊,越往上內存地址越大。
以32位地址操作系統為例,一個進程可擁有的虛擬內存地址範圍為0-2^32。分為兩部分,一部分留給kernel使用(kernel virtual memory),剩下的是進程本身使用, 即圖中的process virtual memory。
普通Java 程序使用的就是process virtual memory.
上圖中最頂端的一部分內存叫做user stack. 這就是題目問的 stack(棧). 中間有個 runtime heap。就是題目中的heap(堆). 他們的名字和數據結構裏的stack(棧) 和 heap(堆) 幾乎沒啥關系。
註意在上圖中,stack(棧)是向下生長的; heap(堆)是向上生長的。
引用這個答案
所以呢,堆棧指針向下移動時分配內存,向上移動時釋放內存。
9種基本類型:
基本類型出現的原因:這種類型是小的、簡單的變量,不需要用new在堆上分配空間(有特例成員變量的基本類型是在堆上),直接置於堆棧中,這樣更高效。
boolean類型所占內存儲空間的大小沒有明確指定,僅定義為能夠取字面值true或false。
高精度數字:
- BigInteger:支持任意精度的整數
- BigDecimal:支持任意精度的定點數
操作與對基本類型所能執行的操作相似,但必須以方法調用方式取代運算符方式來實現。
Java中的數組:
數組會被初始化,而且不能在它的範圍之外被訪問。這種範圍檢查,是以每個數組上少量的內存開銷及運行時的下標檢查為代價(換來安全性和效率)。
2.3 永遠不需要銷毀對象
作用域:
------------------------------------------------------------------
對象的作用域:
Java的作用和基本類型差別很大,new創建一個Java對象後,它可以存活於作用域之外。只要你需要這個對象,就會一直保留下去,直到垃圾回收器辨別到該對象不會再被引用並釋放該對象的內存空間,這樣就消除了內存泄漏的問題。
2.4 創建新的數據類型:類
大多數面向對象的程序設計語言習慣用關鍵子class來表示“我準備告訴你一種新類型的對象看起來像什麽樣子。
class ATypeName { /* Class body goes here */ }
2.4.1 字段和方法
在Java中你所做全部工作就是定義類,產生那些類的對象,以及發送消息給這些對象。
一旦定義了一個類,就可以在類中設置兩種類型的元素:字段(有時被稱作數據成員)和方法(有時被稱作稱成員函數)。
字段可以是任何類型的對象,可以通過其引用與其進行通信;也可以是基本類型中的一種。如果字段是對某個對象的引用,那麽必須初始化該引用,以便使其與一個實際的對象相關聯。
每個對象都有用來存儲其字段的空間;普通字段不能在對象間共享。
class DataOnly { int i; double d; boolean b; }
如何引用一個對象的成員:
在對象引用的名稱之後緊接著一個句點,然後在接著是對象內部的成員名稱:
objectReference.member
如:
DataOnly data = new DataOnly();
data.i = 47;
data.d = 1.1;
data.b = false;
基本成員默認值
若類的某個成員是基本數據類型,即使沒有進行初始化,Java也會確保它獲得一個默認值。
基本類型 | 默認值 |
---|---|
boolean | false |
char | ‘\u0000‘(null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
這些初始值對你的程序來說,可能是不正確的,甚至是不合法的。所以最好明確地對變量進行初始化。
然而上述確保初始化的方法並不適用於(即並非某個類的字段)。
在某個方法定義中有:
int x;
如果忘記了賦初值,Java會在編譯是返回一個錯誤,告訴你此變量沒有初始化。
2.6 構建一個Java程序
static關鍵字:
下面兩種情況需要使用static
- 只想為某特定域分配單一存儲空間,而不去考慮究竟要創建多少對象。
- 某個方法不與包含它的類的任何對象關聯在一起,就是沒有創建對象,也能夠調用這個方法。
class StatiTest{ static i = 47; //可以直接StatiTest.i這樣調用 }
StatiTest st1 = new StatiTest();
StatiTest st2 = new StatiTest();
其中st1.i和st2.i指向同一存儲空間,因此他們具有相同的值47。
同理,調用靜態方法的首選方式:ClassName.method()
。如:
class Incrementable { static void increment() { StaticTest.i++; } }
調用方式一:
Incrementable sf = new Incrementable(); sf.increment();
調用方式二:
Incrementable.increment();
2.9 編碼風格
駝峰風格:
- 類,每個單詞的首字母采用大寫
- 方法、字段及對象等,第一個單詞的首字母采用小寫,其余首字母大寫
總結:
本章容易理解,對Java語言及它的一些基本思想有一個總體的認識,大多數知識點也接觸過,但容易把細節的地方忘記,多看無礙。
java編程思想 第二章