java編程思想 第二章筆記
1.1 用引用操作的對象
java中的一切被視為對象,但是我們操縱的標(biāo)識符實際上是對象的一個引用(reference)懦铺。
所擁有的引用并不一定和一個對象關(guān)聯(lián)起來:
String s; //這里只創(chuàng)建了引用捉貌,沒有對象
String t="asdf"; //沒有指向的引用是不安全的,所以創(chuàng)建時便進行初始化
作者在開始時認為冬念,java的引用趁窃,在語法上更接近C++的引用而不是指針,并且用‘句柄’(handle)來稱呼他急前,在后來改回‘引用’醒陆。同時表述了對于
任何事物都是'按值傳遞'
說法的看法(我竟然沒看懂到底表述了啥,當(dāng)然你可能也沒看懂我想表述啥)
紀(jì)念重新翻開《java編程思想》再次開始思考的第一個問題:
值傳遞和引用傳遞
當(dāng)?shù)谝槐榇致苑^第二章內(nèi)容的時候,我根據(jù)明面總結(jié)出來的結(jié)論是
基本數(shù)據(jù)類型為值傳遞裆针,引用數(shù)據(jù)類型為引用傳遞
多么簡單粗暴刨摩,明了易懂而又美好的結(jié)論寺晌,但是混了這么多年,我本能也知道這個說法有問題澡刹,只是一直沒去深究他呻征。這一次,好好看一看罢浇!
學(xué)習(xí)的第一步:
看博客:某大司馬老師粉絲有話要說陆赋,你們說引用傳遞的都是瓜皮
馬仔同學(xué)為我們提供了一個例子
public class ValueOrRef {
public static void main(String[] args) {
Person zhangsan = new Person("ZHANG San");
changePerson(zhangsan);
zhangsan.printName();
//2,然會嚷闭,最后我們所得到的輸出依然是張三
}
public static void changePerson(Person person){
person = new Person("LI Si");
//1攒岛,如果是按照我們開始的傳遞引用理解,在這一步當(dāng)中胞锰,引用被賦予了新的對象(李四)
}
}
class Person {
String name = "default";
public Person(String name) {
this.name = name;
}
public void changeName(String name){
this.name = name;
}
void printName() {
System.out.println(this.name);
}
}
所以引用傳遞在這里應(yīng)當(dāng)看作是實際引用地址的值傳遞
灾锯,改變指向?qū)ο髮傩詴r,兩者改變時同一個對象胜蛉,當(dāng)改變引用指向的對象(引用地址)時挠进,兩者不再統(tǒng)一指向一個對象。
第一次關(guān)于引用傳遞和值傳遞的思考結(jié)束
1.2 必須由你創(chuàng)建所有對象
程序運行時對象存儲的位置
1,寄存器 案怯,位于處理器內(nèi)部君旦,最快的存儲區(qū),但是數(shù)量有限嘲碱,按需分配不能直接進行控制金砍,C和C++可以向編譯器建議寄存器的分配方式
2,堆棧 麦锯,通常為于RAM(隨機訪問存儲器)恕稠,通過堆棧指針可以從處理器獲得直接支持,堆棧指針向下移動扶欣,分配新內(nèi)存鹅巍,向上移動,釋放內(nèi)存料祠。僅次于寄存器骆捧,創(chuàng)建程序時,java系統(tǒng)必須知道存儲在堆棧中的所有項的確切生命周期髓绽,以便移動堆棧指針敛苇,這限制了程序的靈活性,所以雖然某些Java數(shù)據(jù)存儲在堆棧中——特別是對象引用顺呕,但是java對象并不存儲于其中枫攀。
3括饶,堆 ,一種常規(guī)用途的內(nèi)存池(也在RAM區(qū)域)脓豪,其中保存了Java對象巷帝。和堆棧不同,“內(nèi)存堆”或“堆”(Heap)最吸引人的地方在于編譯器不必知道要從堆里分配多少存儲空間扫夜,也不必知道存儲的數(shù)據(jù)要在堆里停留多長的時間楞泼。因此,用堆保存數(shù)據(jù)時會得到更大的靈活性笤闯。要求創(chuàng)建一個對象時堕阔,只需用new命令編制相關(guān)的代碼即可。執(zhí)行這些代碼時颗味,會在堆里自動進行數(shù)據(jù)的保存超陆。當(dāng)然,為達到這種靈活性浦马,必然會付出一定的代價:在堆里分配存儲空間時會花掉更長的時間时呀!
4,常量存儲 晶默,通常存儲于代碼內(nèi)部谨娜,嵌入式系統(tǒng)中會存儲于ROM(只讀存儲器中)中,避免被修改
說來慚愧磺陡,看著這一段的字有點多趴梢,就準(zhǔn)備上網(wǎng)復(fù)制一下,然后在網(wǎng)上搜了一下發(fā)現(xiàn)了一個GitBook上的一個版本
這里用到的還是‘句柄’這個詞而非‘引用’币他,說明這是老版本的TIJ坞靶,和我手頭版本的對比,他多了一個靜態(tài)存儲
,指類變量的存儲蝴悉。
神奇彰阴,打開我們的搜索器:
java中堆棧(stack)和堆(heap)(還在問靜態(tài)變量放哪里,局部變量放哪里拍冠,靜態(tài)區(qū)在哪里.....進來)
呃硝枉。。倦微。。正压。欣福。這個問題,等我們看完JVM有個更深入的理解再來說吧焦履。
特例拓劝,基本類型
基本類型:一個非引用的變量雏逾,這個變量直接存儲值,并置于堆棧中郑临,因此更加高效栖博。
基本類型會在棧中創(chuàng)建,而對于對象類型厢洞,對象在堆中創(chuàng)建仇让,對象的引用在棧中創(chuàng)建,基本類型由于在棧中躺翻,效率會比較高丧叽,但是可能存在內(nèi)存泄漏的問題
基本類型 | 大小(字節(jié)) | 默認值 | 封裝類 |
---|---|---|---|
byte | 1 | (byte)0 | Byte |
short | 2 | (short)0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0L | Long |
float | 4 | 0.0f | Float |
double | 8 | 0.0d | Double |
boolean | - | false | Boolean |
char | 2 | \u0000(null) | Character |
void | - | - | Void |
數(shù)值類型全都是有符號(正負號)的,所以不必費勁尋找沒有符號的類型公你。
基本數(shù)據(jù)類型擁有自己的“包裝器類”(wrapper)類踊淳,這讓我們可以在堆中創(chuàng)建一個非基本對象,用來標(biāo)識對應(yīng)的基本類型
為什么需要封裝類陕靠?
因為泛型類包括預(yù)定義的集合迂尝,使用的參數(shù)都是對象類型,無法直接使用基本數(shù)據(jù)類型剪芥,所以Java又提供了這些基本類型的封裝類垄开。
void的封裝類主要是用來干什么的,這個有啥用粗俱?
我們暫且就當(dāng):boolean類型占了單獨使用是4個字節(jié)说榆,在數(shù)組中又是1個字節(jié)
不看基本數(shù)據(jù)類型,不看位運算寸认,不知道自己澇签财。雖說天天CRUD這些東西也用不大到,但是該拾起來的還是要拾的偏塞。慢慢來吧唱蒸。
關(guān)于char中英文和數(shù)字的轉(zhuǎn)化(ASCII )關(guān)于編碼的基礎(chǔ)補充
Java中的ASCII、Unicode和UTF-8字符編碼集
關(guān)于最大時值最小值的問題灸叼,額神汹。。古今。屁魏。。捉腥。慢慢來氓拼!
高精度數(shù)字
//BigInteger 支持任意精度的整數(shù)
//BigDecimal 支持任意精度的定點數(shù)
java中的數(shù)組
創(chuàng)建數(shù)組時,實際上時創(chuàng)建了一個引用數(shù)組,并且每個引用都會自動被初始化為一個特定的值桃漾,該值擁有自己的關(guān)鍵字null~~
創(chuàng)建基本類型數(shù)據(jù)類型的數(shù)組坏匪,編譯器會保證這種數(shù)組的初始化,因為它會將這種數(shù)組所占的內(nèi)存全部置0
boolean和char會是什么
應(yīng)該是基本數(shù)據(jù)類型的默認值撬统,boolean默認為了false适滓,但是char的默認值感覺有點怪怪的(\u0000(null)),這個要如何理解
搜索引擎:
答案1:
答案2:
照著第二個答案寫了個小測試:
public class Base {
private static char a ;
public static void main(String[] args) {
System.out.println(a=='\u0000'); //true
char s = '\u0000';
Character character = s;
System.out.println(character=='\u0000');//true
System.out.println(character==null);//false
}
}
好吧恋追,可能是我的理解有偏差凭迹,并不能完全當(dāng)作null來使用,應(yīng)該還是像第一種說法几于,這個null就是Unicode里的null蕊苗。
并且在char的封裝類Character類中,最小值就是'\u0000'
public static final char MIN_VALUE = '\u0000';
1.3 永遠不要銷毀對象
作用域(scope)
決定了其內(nèi)定義的變量名的可見性和生命周期沿彭,作用域由花括號決定
{
int x = 12;
{
int x = 95;//java中不允許如此操作
}
}
對象的作用域
引用會在作用域的終點消失朽砰,但是引用指向的對象仍繼續(xù)占據(jù)內(nèi)存空間。
java的垃圾回收器喉刘,會監(jiān)視用new創(chuàng)建的所有對象瞧柔,并在對象不會再被引用時,釋放對象的內(nèi)存空間睦裳。
1.4 創(chuàng)建新的數(shù)據(jù)類型:類
關(guān)鍵字:class
類中可以設(shè)置兩種元素:1造锅,字段(域,數(shù)據(jù)成員) 2廉邑,方法(成員函數(shù))
通過 類名.字段名
獲取一個對象的成員
- 如果字段是某個對象的引用哥蔚,那么必須初始化該引用
- 如果類的某個成員是基本數(shù)據(jù)類型,即使不進行初始化蛛蒙,java也會確保它具有一個默認值糙箍。局部變量不具備這個特性。
1.5 方法牵祟,參數(shù)和返回值
方法的基本組成部分:名稱深夯,參數(shù),返回值诺苹,方法體
方法名和參數(shù)列表咕晋,合稱為方法簽名
,能唯一 的標(biāo)識出某個方法
方法的調(diào)用 類名.方法名(參數(shù)列表)
參數(shù)列表
值傳遞和引用傳遞收奔,上面說過
void nothing(){
return ;
}
如果返回類型為void掌呜,那么 return 關(guān)鍵字只用來退出方法
2.6 構(gòu)建Java程序
名字可見性
名字空間:反過來使用自己的Internet域名作為工作空間名,以保證類庫的獨一無二
java1.0和1.1 中 擴展名com,edu,org,net 等都約定為大寫坪哄,java2開發(fā)到一半時站辉,設(shè)計者發(fā)現(xiàn)這樣會引發(fā)一些問題呢撞,于是,現(xiàn)在整個包名都是小寫饰剥。
我沒能找到到底為什么要小寫,網(wǎng)上的主要說法有兩種:
1摧阅,系統(tǒng)對大小寫是否敏感汰蓉,考慮兼容性。
2棒卷,避免混淆對類的識別 com.Student 顾孽,看著也啥影像
運用其他構(gòu)件
當(dāng)兩個類在同一個源文件中時,定義順序并不影響調(diào)用(java中消除了所謂的向前引用問題)
不在同一個源文件中時比规,可以使用import
關(guān)鍵字導(dǎo)入
import java.util.ArrayList;
import java.util.*;
static 關(guān)鍵字
為某特定域分配單一固定存儲空間若厚,不受創(chuàng)建對象多少的影響,甚至根本不需要創(chuàng)建對象蜒什,只與類有關(guān)聯(lián)测秸。
static域
或方法
,不會與包含他的那個類的任何對象實例關(guān)聯(lián)灾常,我們稱之為類數(shù)據(jù)和類方法
調(diào)用:
1. 對象名.域名(方法名)
2. 類名.域名(方法名)-----首選霎冯,強調(diào)了static結(jié)構(gòu),同時為編譯器進行優(yōu)化提供了條件
static 方法不能簡單的調(diào)用其他非static域或者方法钞瀑,因為他和當(dāng)前對象并沒有關(guān)系沈撞。
static域和普通域有較大差別,static域只有一份存儲空間雕什,而static方法和普通方法的差距并不大缠俺。
1.7 第一個java程序
在所有個類中,都會默認導(dǎo)入java.lang包
類名必須同文件名相同
main(String[] args)
作用:agrs 用來存儲命令行參數(shù) 贷岸,java在命令行運行的時候要用到
java Test value1 value2
//后面就是兩個參數(shù)壹士,在main里面args[]就是兩個長度的數(shù)組value1存在args[1]中,value2存在args[2]中凰盔。
//args[0]存儲的是命令墓卦,其后才是參數(shù)!
2.8 注釋和嵌入文檔
跳一跳
2.9 編碼風(fēng)格
駝峰風(fēng)格
:
類名首字母大寫户敬,多個單詞組成緊拼在一起(不要使用下劃線)落剪,每個單詞首字母大寫,開頭兩個首字母如果為單詞縮寫尿庐,不要都戴大寫忠怖。
WaHaHa