java基礎 —— 概述Java語言:
JDK(Java Development Kit)開發工具包,提供Java的開發環境和運行環境 --> 適合于開發
JRE(Java Runtime Environment)Java運行時環境,包含Java虛擬機(JVM) --> 適合于運行
Java代碼在JDK下編譯,會生成.class文件,再使用JVM運行.class文件(字節碼文件)
Java基礎語法:
- (1) 命名規范:
- 1. 類和接口:用若干名詞或詞組組成,首字母均大寫。如 JHelloWorld。
- 2. 方法名:動詞或名詞詞組組成,首字母小寫,其余單詞首字母大寫。如 setAge()。
- 3. 常量名:全部使用大寫,并用下劃線分隔單詞。如 HIGH_NAME。
- 4. 變量名:名詞或詞組,首字母小寫,其余大寫,如 authorName。
- 標識符:首字母必須是字母、下劃線或者美元符號,可以由字母,數字,下劃線與美元符號組成,不能有空格。
- (2) 基本數據類型:
- 1. 布爾型: boolean (1字節)
- 2. 字符型: char (2字節)
- 3. 整型: byte, short, int, long (1字節,2字節,4字節,8字節)
- 4. 浮點型 float, double (4字節,8字節)
- 數據類型強弱關系: byte < char(short) < int < long < float < double
- 弱類型可以自動轉換為強類型,但是強類型不能隱式轉換成弱類型,只能使用強制轉換。
- (3) JVM的內存空間:
- 1. 寄存器 (Registers):最快的保存區域,位于處理器內部,由編譯器分配。主要作用是記錄當前線程所執行的字節碼的行號。字節碼解釋器工作時就是通過改變當前線程的程序
- 2. 棧 (Stack):JVM的棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放的是當前線程中局部基本類型的變量(八種)、部分的返回結果以及Stack Frame,非基本類型的對象(引用類型)在JVM棧上只存放一個指向堆內存的地址,因此Java中的基本類型變量采用值傳遞,而引用類型對象采用引用傳遞。由于棧是線程私有的,因此內存分配上非常高效,且當線程運行完畢后,這些內存也就被自動回收了。當棧請求深度大于允許的深度時,會拋出StackOverflowError的錯誤,可以通過-Xss來指定站的大小。而如果內存不足時,會拋出OutOfMemoryError錯誤。
- 3. 堆 (Heap):用來存儲對象實例以及數組值,所有通過new創建的對象內存都在這里分配。堆中的對象內存需要等待GC(垃圾回收機制)進行回收,堆內存在32位操作系統上最大為2G,在64位操作系統上則沒有限制,其大小通過-Xms(啟動最小堆內存,默認物理內存的1/64,小于1G)和-Xmx(啟動最大堆內存,默認物理內存的1/4)來控制。默認當空余堆內存小于40%時,JVM會增大堆的大小到-Xmx指定的大小,可通過-XX:MinHeapFreeRatio來指定這個比例。當空余堆內存大于70%時,JVM會將堆內存的大小往-Xms指定的大小調整,可通過-XX:MaxHeapFreeRatio=來指定這個比例,但對于運行系統而言,為了避免頻繁的改變堆內存的大小,通常都會將-Xms和-Xmx的值設置成一樣。當堆中需要使用的內存超過其允許的大小時,會拋出OutOfMemory的錯誤信息。
- 4. 方法區域(MethodArea):在Java虛擬機規范中,方法區被描述為堆的一個邏輯部分,但一般與堆區分開。存放了加載的類信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的常量、類中的Field信息、類中的方法信息,當開發人員在程序中通過Class對象中的getName、isInterface等方法來獲取信息時,這些數據都來源于方法區域,可見方法區域的重要性。同樣,方法區域也是全局共享的,它在虛擬機啟動時在一定的條件下也會被GC,當方法區域需要使用的內存超過其允許的大小時,會拋出OutOfMemory的錯誤信息。在Sun JDK中這塊區域對應的為PermanetGeneration,又稱為持久代,默認為64M,可通過-XX:PermSize以及-XX:MaxPermSize來指定其大小。
- 5. 運行時常量池(RuntimeConstant Pool):是方法區的一部分。類似C中的符號表,存放的為類中的固定的常量信息、方法和Field的引用信息等,其空間從方法區域中分配。類或接口的常量池在該類的class文件被java虛擬機成功裝載時分配。
- 6.本地方法堆棧(NativeMethod Stacks):與上述棧的作用非常相似,上述的棧主要為虛擬機執行Java方法(字節碼文件)服務,而本地方法堆棧則是為Native方法服務。本地方法堆棧也會拋出StackOverflowError和OutOfMemoryError錯誤。
- 例如有這么一段代碼:
public class A { public static void main(String[]args){ String a="a"; String b="b"; String ab="ab"; System.out.PRintln((a+b)==ab); // false System.out.println(("a"+"b")==ab); // true final String afinal="a"; String result=afinal+"b"; System.out.println(result==ab); // true String plus=a+"b"; System.out.println(plus==ab); // false System.out.println(plus.intern()==ab); // true } } - 分析下上面代碼執行的結果,可通過javap –verbose A來輔助理解分析。
- a+b是兩個變量相加,需要到運行時才能確定其值,到運行時后JVM會為兩者相加后產生一個新的對象,因此a+b==ab的結果為false。
- "a"+”b”是常量,在編譯時JVM已經將其變為"ab"字符串了,而ab="ab"也是常量,這兩者在常量池即為同一地址,因此("a"+"b")==ab為true。
- result=afinal+"b",afinal是個final的變量, result在編譯時也已經被轉變為了"ab",和"ab"在常量池中同樣為同一地址,因此result==ab為true。
- plus和a+b的情況是相同的,因此plus==ab為false。這里的不同點在于調用了plus.intern()方法,這個方法的作用是獲取plus指向的常量池地址,因此plus.intern()==ab為true。
- 這里注意一點,通常的JVM垃圾回收指的是堆內存和代碼區域的回收,其他區域的回收都由JVM簡單的按生命周期來進行管理。
- (4) 變量分配機制:若變量為基本數據類型,則會在棧中開辟相應大小的空間,用于存放該數據;若變量為引用類型數據,則會在棧內存中生成相應的引用值(地址),即對象的實際地址的編制,再在堆內存中生成該對象的相應空間和數據。
MyDate date; date = new MyDate(8,8,2008)
- 首先在棧內存中分配了一個32位的對象空間(沒有實例化,不能被使用),然后實例化了一個對象,此時生成了對象的哈希碼(地址),并將這個值賦值給date。這樣,棧內存中就有了相應的哈希碼,而堆內存中也生成了相應的空間?!?/li>
- (5) 輸入參數的方式:
- 1. 使用main方法的String[] args參數,可以在編譯時加入。
- 2. main方法內定義參數常量。
- 3. 使用JOptionalPane類彈框輸入。(界面輸入)
- 4. 使用輸入流進行輸入。(System.in.read()方法或BufferedReader對象)。
InputStreamReader in = new InputStreamReader(System.in);BufferedReader buf = new BufferedReader(in);//String s = buf.readLine(); --> 讀一行while(!"".equals(s)){ ...; s = buf.readLine();}Scanner s = new Scanner(System.in);String str = s.nextLine();
- (6) 形參與實參:基本數據類型使用值傳遞;若為引用類型,則是地址傳遞,即建立了同一空間的引用。
- (7) this指針:解決了方法內部形參與成員之間命名沖突的同名隱藏問題,并可以調用內部的構造函數。
- (8) static關鍵字:
- 1. 類方法:
- 1) 類方法只能訪問方法體內的局部變量、參數和靜態變量。
- 2) 不能出現this和super,因為不存在唯一的對象。
- 3) 若想使用非靜態方法,一定要生成局部的類對象,再對象.方法來調用。
- 2. static初始化塊:無法人為調用,只在其所在的類被載入JVM內存時才會自動執行一次(僅執行一次)。
- 3. 非static初始化塊:在對象創建時,構造方法執行之前會調用一次(視對象的聲明而定)。
- 4. 靜態導入:只導入程序包中的static變量和方法。
import static 包名.類名.靜態屬性|靜態方法|*
- (9) final關鍵字:
- 1. 用final修飾的類時,表示最終類,即不能被繼承的類。
- 2. 用final修飾的方法時,表示該方法不能被其所在的類的子類覆蓋。
- 3. final修飾方法的參數時,表示該方法不希望被傳進來的參數在方法內被改變。