注釋
先講注釋惕味,程序與注釋的關(guān)系就好比人和衣服的關(guān)系。不寫注釋玉锌,并不會影響程序的執(zhí)行名挥,人不穿衣服也能生存,但誰會不穿衣服呢主守?人穿衣服的時候禀倔,還想穿的美美的呢!所以参淫,注釋也要寫的美蹋艺。
注釋的作用?
- 增加代碼可維護(hù)性黄刚,就是讓人知道這代碼用來干嘛的
- 調(diào)試程序的一種方式
- 使用 Annotation 來簡化代碼開發(fā),代替 xml 配置文件
注釋的分類
- 說明性注釋:描述類民效、方法和屬性的注釋憔维,用文檔注釋書寫
- 功能性注釋:描述屬性在方法中的功能的注釋,一般用單行注釋書寫
關(guān)于 Javadoc
至于具體的注釋風(fēng)格畏邢,以及 JDK 提供的 Javadoc 程序用來生成 API 文檔的相關(guān)細(xì)節(jié)业扒,在實際編碼時用到了慢慢補(bǔ)充就可以了。
- Javadoc 默認(rèn)只能提取 public 和 protected 修飾的方法和字段
- Javadoc 默認(rèn)只能提取 public 修飾的類和接口
- 文檔注釋中可以插入 HTML 標(biāo)簽舒萎,用于排版
- @author程储,@param 等常用的標(biāo)簽,慢慢積累
- @Deprecation 英文含義是棄用的意思臂寝≌吕穑可以用來修飾類、屬性咆贬、方法败徊。JDK 提供的標(biāo)準(zhǔn)類會隨著版本不斷更新,所以會出現(xiàn)一些之前設(shè)計的不好的掏缎,后續(xù)版本提供了新的皱蹦、更好的替代品,所以把之前的設(shè)計用@Deprecation 注解來標(biāo)注它已經(jīng)過時了眷蜈,不推薦使用沪哺。但是之所以仍然存在,沒有徹底剔除掉它酌儒,是為了向下兼容辜妓。避免以前的項目當(dāng)中用到了這些方法,而導(dǎo)致項目不能正確運行。這也是沒辦法的事情了嫌拣!
包導(dǎo)入柔袁,包聲明
import 和 package 都是在對字節(jié)碼文件進(jìn)行操作,和源碼沒關(guān)系异逐,因為源碼是給人看的捶索,字節(jié)碼才是給機(jī)器運行的,對機(jī)器而言根本就不存在源碼這種東西灰瞻。import 是用來指定去哪里找字節(jié)碼文件腥例,package 是用來指定這個 java 文件編譯后的字節(jié)碼放到指定的目錄下。平時看到的分包管理源代碼的機(jī)制酝润,其實是 IDE 工具的一廂情愿燎竖,碰巧它能用來分類管理源代碼而已。不使用 IDE 工具的時候要销,源代碼根本就不需要按照包名來建立相應(yīng)文件夾管理构回,同樣可以直接編譯,成功運行疏咐。這便是一個有力證明!
包導(dǎo)入 import 關(guān)鍵字的作用是
- 當(dāng)該字節(jié)碼文件在執(zhí)行過程中浑塞,需要用到了本包中沒有的字節(jié)碼文件時,就會主動在當(dāng)前目錄下去尋找 import 關(guān)鍵字指明的字節(jié)碼文件酌壕,import 關(guān)鍵字后面接的就是一個類字節(jié)碼文件的全名。
包聲明 package 關(guān)鍵字有以下作用
- 從源碼的角度來看卵牍,按照包名創(chuàng)建相應(yīng)文件夾來管理 .java 源文件果港,體現(xiàn)了分包管理的機(jī)制京腥,也為 java 程序的權(quán)限機(jī)制提供了必要條件。
- 從字節(jié)碼的角度看溅蛉,一個類的完整名字(包名.類名)是把包名也包含進(jìn)去了的。所以說船侧,當(dāng) java.exe 程序需要執(zhí)行字節(jié)碼文件的真正含義是,在當(dāng)前目錄下執(zhí)行某個名字為類的全名的字節(jié)碼文件镜撩,即必須指明類的全名队塘!
package practice1;
import practice2.MyPoint2;
public class MyPoint1 {
public static void main(String[] args) {
MyPoint1 p = new MyPoint1();
System.out.println(p.getClass().getName());
System.out.println("MyPoint1");
//同包下的類
Person person1 = new Person();
System.out.println(person1);
//practice2包下的類
MyPoint2 point2 = new MyPoint2();
System.out.println(point2);
}
}
結(jié)合以上代碼,從 IDE 工具的角度來理解為什么是這樣的宜鸯。只有理解IDE 為你做的每一個工作憔古,才真正達(dá)到了可以使用 IDE 的層次。
新建一個工程為 test 淋袖,在 practice1 包下新建 MyPoint1 和 Person 類鸿市,在 practice2 包下新建 MyPoint2 類。以上在文件資源管理器中看到的情況是即碗,IDE 幫你在磁盤中創(chuàng)建 test 目錄焰情,并且它下面還有 bin 和 src 目錄,src 目錄下按照包名創(chuàng)建相應(yīng)文件夾來放置 .java 源文件剥懒。
當(dāng)你在 IDE 工具中點擊運行按鈕時内舟,其實 IDE 幫你做了以下工作。首先在 test 目錄下執(zhí)行 javac -d bin src/*/*.java
初橘,即把 src 目錄下的所有子目錄以及各子目錄下的 .java 都編譯了验游,按照包名在 bin 目錄下組織存放相關(guān)的 .class 文件。
然后保檐,在 bin 目錄下執(zhí)行java practice1.MyPoint1
批狱,JVM 就會加載practice1.MyPoint1.class 到內(nèi)存中,開始執(zhí)行程序展东。
所以,以后在使用 IDE 工具的圖形化界面操作的時候炒俱,多想想它在底層都為你做了什么盐肃?只有這樣才能到達(dá)使用 IDE 工具的做高境界,使用 IDE 工具是為了幫助自己簡化工作权悟,而不是讓自己依賴 IDE 砸王,沒有 IDE 就無法工作了。
變量
所謂變量就是在內(nèi)存當(dāng)中按照其數(shù)據(jù)類型分配固定大小的一個存儲空間峦阁,專門用來存儲數(shù)據(jù)谦铃,這個數(shù)據(jù)可以隨時改變。與之相對應(yīng)的叫做常量榔昔,即它在內(nèi)存當(dāng)中的值不可改變驹闰。
按照數(shù)據(jù)類型的角度分類
變量按照數(shù)據(jù)類型的角度分類,可以分為基本數(shù)據(jù)類型變量和引用數(shù)據(jù)類型變量撒会。
基本數(shù)據(jù)類型變量
Java 中基本數(shù)據(jù)類型變量無論在哪種操作系統(tǒng)嘹朗、哪種硬件架構(gòu)中,它們都占據(jù)固定不變的存儲大小诵肛。能做到這一點就是因為 java 程序是運行在虛擬機(jī)上的屹培,這也是 java 程序移植性更好的原因之一。
引用數(shù)據(jù)類型變量
對于引用數(shù)據(jù)類型變量,如果把對象比作電視機(jī)的話褪秀,那么遙控器就是這個對象的引用蓄诽。在 Java 這種完全面向?qū)ο蟮恼Z言中,想要對對象進(jìn)行操作媒吗,只要擁有這個對象的引用就可以了。這個引用可以任意帶走蝴猪,無論在哪里自阱,都可以通過它來使用對象。這在復(fù)雜的分層項目當(dāng)中趋箩,將對象引用的值叫确,也就是對象在內(nèi)存中的地址芍锦,作為參數(shù)到處傳遞的過程中娄琉,體現(xiàn)的淋漓盡致。這個比喻出自《 Java 編程思想》一書票腰。
按照內(nèi)存中的不同位置分類
變量按照內(nèi)存中的不同位置分類杏慰,可以分為局部變量炼鞠,實例全局變量和靜態(tài)全局變量。要真正理解變量之間的區(qū)別完域,其實只要心中時刻想著內(nèi)存圖吟税,理解它在內(nèi)存當(dāng)中的劃分,就不可能會出錯肖抱。
局部變量
局部變量定義在方法和類的語句塊里面意述,作用范圍有限吮蛹,它存放在棧區(qū)潮针。
當(dāng)局部變量和全局變量在作用域內(nèi)沖突時,會被默認(rèn)認(rèn)為是局部變量瓣戚,正所謂山高皇帝遠(yuǎn)嘛子库!這完全可以通過規(guī)范化命名來避免沖突啊矗晃。
局部變量是在對應(yīng)的方法棧幀里面分配空間的张症,由于棧這種數(shù)據(jù)結(jié)構(gòu)本身是不穩(wěn)定的,所以并不需要 GC 來負(fù)責(zé)回收內(nèi)存。
所有在棧里面的局部變量都不會有默認(rèn)的值恭理,只是一個隨機(jī)的垃圾值。
方法的形參也是這個方法內(nèi)部的局部變量涯保,在方法被調(diào)用時有了初始值
全局變量定義在類里頭周伦,且在被創(chuàng)建的時候就會根據(jù)其數(shù)據(jù)類型有一個默認(rèn)的初始值专挪,它存放在堆區(qū)或者方法區(qū)片排。
靜態(tài)全局變量
靜態(tài)全局變量在類的字節(jié)碼文件被加載到類代碼區(qū)時率寡,JVM 下一步要做的就是在靜態(tài)數(shù)據(jù)區(qū)給靜態(tài)全局變量開辟空間倚搬。
靜態(tài)全局變量會和該類進(jìn)行靜態(tài)綁定每界,并且當(dāng)該類的對象在堆區(qū)開辟空間時,也會有一個和靜態(tài)變量同名的實例變量存在庙楚,指向靜態(tài)數(shù)據(jù)區(qū)的內(nèi)存空間谐岁。也就是說這個實例全局變量的值是該靜態(tài)數(shù)據(jù)在靜態(tài)數(shù)據(jù)區(qū)的地址伊佃!
類是通過靜態(tài)綁定機(jī)制來調(diào)用靜態(tài)方法和變量的,而對象則是通過引用機(jī)制實現(xiàn)的此功能塞祈。
由于靜態(tài)全局變量是依賴于類而存在帅涂,所以它的生存周期很長,一直在內(nèi)存中存在斯议,所以沒事還是不要亂用靜態(tài)全局變量哼御。同時也會增大程序的耦合性焊唬,因為這個類和這個類的所有對象都可以使用和改變這個屬性。
實例全局變量
實例全局變量是依賴于對象而存在的液肌,每一個對象都完整且單獨擁有這些實例屬性嗦哆。理解了每一個對象在堆內(nèi)存當(dāng)中都有一個完整、獨立的內(nèi)存空間吝秕,其他好像沒什么好說的了烁峭。
對象盡量不要創(chuàng)建在普通方法中,當(dāng)該方法退棧時缩挑,局部變量消失鬓梅,它在堆內(nèi)存的對象會變成游離態(tài),變成了垃圾芥丧。這一塊內(nèi)存區(qū)域因為沒有對象的句柄而用不上续担,又無法用來創(chuàng)建其他對象活孩,就造成了內(nèi)存泄露。當(dāng)一塊內(nèi)存沒有使用價值询兴,又無法被重新利用時诗舰,就好像這塊內(nèi)存沒有了一樣,就叫做內(nèi)存泄漏眶根。
不是有 GC 嗎缭保?不會回收耙章睢隆夯?你還真是 too young 啊厘肮!Java 垃圾回收機(jī)制盡管有用也沒有那么牛皮吧睦番?即使是自己生產(chǎn)對象,使用內(nèi)存的 c++ 程序員巩检,都沒法用好內(nèi)存兢哭,一個不了解你的程序能這么智能夫嗓?所以說舍咖,GC 只是能夠改善內(nèi)存谎仲,不可能那么理想化的。
Java 中只有值傳遞
Java 中的實參和形參中只有值傳遞夹姥。棧中的基本類型變量直接把它的內(nèi)容給了形參辙售,給的是值旦部。棧中的引用類型變量給的是地址士八,這是因為它的內(nèi)容就是對象在堆區(qū)的地址啊,他給的也是值婚度。