1、ClassLoaderjava
當運行一個Java 程序時,JVM啓動,運行bootstrap classLoader(啓動類加載器),將Java核心的API加載進來;接着調用ExtClassLoader加載擴展API,最後AppClassLoader加載CLASSPATH目錄下定義的Class;這就是一個程序最基本的加載過程。程序員
最經常使用的兩個方法應該是ClassLoader.loadClass(String name , boolean resolve)和Class.forName(String name) ,這兩個方法都是用來加載Class的,但在做用上卻有一些區別。編程
loadClass的方法是被保護的,用戶可以直接調用的是loadClass(String name) , resolve默認爲false,即不解析類,則說明loadClass在加載類的時候不對該類進行解析,所以不會初始化該類。forName(String name ) 等同於Class.forName("className",true,CALLCLASS.class.getClassLoader),即在加載的時候就會將該類進行解釋和初始化。bootstrap
在JVM加載類時須要通過三個步驟:裝載、鏈接、初始化。安全
裝載:網絡
1.經過類的全名產生對應類的二進制數據流。(注意,若是沒找到對應類文件,只有在類實際使用時才拋出錯誤。)數據結構
2.分析並將這些二進制數據流轉換爲方法區(JVM 的架構:方法區、堆,棧,本地方法棧,pc 寄存器)特定的數據結構(這些數據結構是實現有關的,不一樣 JVM 有不一樣實現)。這裏處理了部分檢驗,好比類文件的魔數的驗證,檢查文件是否過長或者太短,肯定是否有父類(除了 Obecjt 類)。架構
3.建立對應類的 java.lang.Class 實例(注意,有了對應的 Class 實例,並不意味着這個類已經完成了加載鏈連接!)。函數
鏈接:spa
1.驗證,即驗證class是否符合規則,如檢查 final class 又沒有被繼承,檢查靜態變量的正確性等等;
2.準備,對類的成員變量分配空間。雖然有初始值,但這個時候不會對他們進行初始化(由於這裏不會執行任何 Java 代碼)。具體以下:全部原始類型的值都爲 0。如 float: 0f, int: 0, boolean: 0(注意 boolean 底層實現大多使用 int),引用類型則爲 null。
3.解釋,爲類、接口、方法、成員變量的符號引用定位直接引用。這一步是可選的,能夠在符號引用第一次被使用時完成,即所謂的延遲解析(late resolution)。但對用戶而言,這一步永遠是延遲解析的,即便運行時會執行 early resolution,但程序不會顯示的在第一次判斷出錯誤時拋出錯誤,而會在對應的類第一次主動使用的時候拋出錯誤!
初始化:
1.若是基類沒有被初始化,初始化基類。
2.有類構造函數,則執行類構造函數。
說明:Java中字符只以一種形式存在,那就是Unicode。
在生成對象的過程當中,會先初始化對象的成員變量,而後再執行構造器。也就是說類中的變量會在任何方法(包括構造器)調用以前獲得初始化,即便變量散步於方法定義之間。父類的構造器調用以及初始化過程必定在子類的前面,即父類的構造函數必定會被調用。
2、類型轉換
簡單數據類型由低級到高級的順序爲(byte,short,char)- int - long - float - double ;
低級到高級可自動轉換,高級到低級、同級之間都須要強制轉換。
1. 默認1.0表示的是double型,若是須要表示float,需寫爲1.0f。
2. 當char x= 'x' ; int i = 10; 公式false? i : x 輸出的值爲120,由於二者都是變量,會將低級升級到高級的表示形式;false?10:x ,x的輸出仍爲x,是由於Java編程規範中提到當兩個表達式有一個是常量表達式(10),另一個是T類型,且常量表達式能夠被T表示時,輸出結果是T類型。
3. 若byte a = 1, byte b = 2 , a * b 的數據類型倒是int ,由於在計算時會將byte,char 類型數據都轉爲int.
4.三目運算是右結合性。
3、異常
Error和exception都是繼承自Throwable類。
Error是不可控制的,常常用來表示系統錯誤或者底層資源的錯誤。
Exception能夠是可被控制(checked) 或不可控制的(unchecked),應該在應用層進行處理,throw表示拋出一個異常,throws是在方法體外部聲明可能會拋出某些異常。
程序必須捕獲或聲明全部的非運行時異常。
4、串行化
Java的「對象串行化」可以將實現了Serializable接口的對象裝換成一組byte,這樣往後要用的時候就可以把這些對象恢復出來,並從新構建該對象。串行化主要任務是寫出對象實例變量的數值,若是變量是另外一對象的引用,則引用對象也要串行化,這個過程是遞歸的。
串行化可以保存對象的非靜態成員變量,即不能保存任何成員方法和靜態的成員變量,且保存的只是變量的值,對於任何修飾符都不能保存。
transient 關鍵字,用來表示一個域不是該串行化的一部分。該關鍵字使用場景如:爲了保證用戶信息的安全性,僅串行化用戶名而不串行化用戶密碼。由於串行化事後可能會將數據存放至磁盤或網絡上,不在java安全機制控制之中。
5、內存管理
Java 的內存管理就是內存的分配和釋放,程序員須要經過關鍵字new來爲每一個對象申請內存空間,全部的對象都在堆中分配空間。
對象的釋放則是由垃圾回收器來管理。判斷一塊內存空間是否符合垃圾回收器的收集標準只有兩個:
1. 給對象賦予空值null , 之後再也沒有調用過。
2. 給對象賦予新值,即從新分配了內存。
爲了更好地瞭解垃圾回收機制,咱們能夠用有向圖來表示,即對象爲有向圖的頂點,引用關係爲有向圖的邊,有向邊從引用者指向被引用者。從有向圖的起始點(如main進程)不可達的對象都時符合垃圾回收機制回收的對象。
內存泄露就是存在一些被分配的對象,這些對象包含兩個特色:
1. 在有向圖中對象是可達的。
2. 對象是無用的,即這些對象永遠不會再被使用。
Object 的clone方法是protected ,不能直接調用,子類必須實現Cloneable接口。