[TOC]
# 類裝載過程

裝載:通過累的全限定名獲取二進制字節流,將二進制字節流轉換成方法區中的運行時數據結構,在內存中生成Java.lang.class對象;
鏈接:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查導入類或接口的二進制數據的正確性;(文件格式驗證,元數據驗證,字節碼驗證,符號引用驗證)
準備:給類的靜態變量分配并初始化存儲空間;
解析:將常量池中的符號引用轉成直接引用;
初始化:激活類的靜態變量的初始化Java代碼和靜態Java代碼塊,并初始化程序員設置的變量值。
# 簡介
Java在需要使用類的時候,才會將類加載,Java的類加載是由類加載器來完成的。當在命令行模式下執行java XXX.class指令后,java運行程序會嘗試找到JRE安裝的所在目錄,然后尋找jvm.dll(默認是在JRE目錄下bin\client目錄中),接著啟動JVM并進行初始化動作,產生Bootstrap Loader,Bootstrap Loader會加載Extended Loader,并設定Extende Loader的parent為Bootstrap Loader。接著Bootstrap Loader會加載System Loader,并將System Loader的parent設定為Extended Loader。
Bootstrap Loader通常由C編寫而成,Extended Loader是由Java編寫而成,實際是對應于sun.misc.Launcher$ExtClassLoader(Launcher中的內部類).System Loader是由java編寫而成,實際對你關于 sun.misc.Launcher$AppClassLoader(Launcher中的內部類)。
Bootstrap Loader會搜索系統參數sun.boot.class.path中指定位置的類,默認是JRE所在目錄的classes下的.class文件,或lib目錄下.jar文件中(如tr.jar)的類并加載。可用System.getProperty(“sun.boot.class.path”)來顯示sun.boot.class.path中指定的路徑。
Extended Loader是由Java編寫而成,會搜索系統參數java.ext.dirs中指定位置的類,默認是JRE目錄下的lib\ext\classes目錄下的.class文件,或lib\ext目錄下的.jar文件中的類并加載。
System Loader是由java編寫而成,會搜索系統參數java.class.path中指定位置的類,也就是Classpath所指定的路徑,默認是當前工作路徑下的.class文件。
在加載類時,每個類加載器會先將加載類的任務交給其parent,如果parent找不到,再由自己負責加載。所以在加載類順序為:Bootstrap Loader——》Extended Loader——》System Loader的順序來尋找類,若都找不到,會拋出NoClassDefFoundError.
類加載器在Java中是以java.lang.ClassLoader類型存在,每一個類被加載后,都會有一個Class的實例來代表,而每個Class的實例都會記得自己是由哪個ClassLoader加載的。可以由Class的getClassLoader()取得加載該類的ClassLoader,而從ClassLoader的getParent()方法可以取得自己的parent
# 分析 Class.forName()和ClassLoader.loadClass
~~~
Class.forName(className)方法,內部實際調用的方法是 Class.forName(className,true,classloader);
第2個boolean參數表示類是否需要初始化, Class.forName(className)默認是需要初始化。
一旦初始化,就會觸發目標對象的 static塊代碼執行,static參數也也會被再次初始化。
ClassLoader.loadClass(className)方法,內部實際調用的方法是 ClassLoader.loadClass(className,false);
第2個 boolean參數,表示目標對象是否進行鏈接,false表示不進行鏈接,由上面介紹可以,
不進行鏈接意味著不進行包括初始化等一些列步驟,那么靜態塊和靜態對象就不會得到執行
~~~
# 數據庫鏈接為什么使用Class.forName(className)
JDBC Driver源碼如下,因此使用Class.forName(classname)才能在反射回去類的時候執行static塊
~~~
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
~~~
- 基礎
- 編譯和安裝
- scanner類(鍵盤錄入)
- Random類(隨機數)
- 數組
- 方法
- 類
- ArrayList集合
- char與int
- eclipse
- IDEA
- 變量與常量
- 常用API
- String,StringBuffer,StringBuilder
- 正則,Date,DateFormat,Calendar
- 包裝類,System,Math,Arrays,BigInteger,BigDecimal
- 集合,迭代器,增強for,泛型
- List,set,判斷集合唯一
- map,Entry,HashMap,Collections
- 異常
- IO
- File
- 遞歸
- 字節流
- 字符流
- IO流分類
- 轉換流
- 緩沖流
- 流的操作規律
- properties
- 序列化流與反序列化流
- 打印流
- commons-IO
- IO流總結
- 多線程
- 線程池
- 線程安全
- 線程同步
- 死鎖
- lock接口
- ThreadLoad
- 等待喚醒機制
- 線程狀態
- jdbc
- DBUtils
- 連接池DBCP
- c3p0連接池
- 網絡編程
- 多線程socket上傳圖片
- 反射
- xml
- 設計模式
- 裝飾器模式
- web service
- tomcat
- Servlet
- response
- request
- session和cookie
- JSP
- EL
- JSTL
- 事務
- 監聽器Listener
- 過濾器Filter
- json
- linux安裝軟件
- 反射詳解
- 類加載器和注解
- 動態代理
- jedis
- Hibernate
- 簡介
- 創建映射文件
- Hibernate核心配置文件
- 事務和增刪改查
- HibernateUtils
- 持久化對象的三種狀態
- 檢索方式
- query
- Criteria
- SQLQuery
- 持久化類
- 主鍵生成策略
- 緩存
- 事務管理
- 關系映射
- 注解
- 優化
- struts2
- 搭建
- 配置詳解
- Action
- 結果跳轉方式
- 訪問ServletAPI方式
- 如何獲得參數
- OGNL表達式
- valueStack 值棧
- Interceptor攔截器
- spring
- 導包
- IOC和DI
- Bean獲取與實例化
- Bean屬性注入
- spring注解
- 注解分層
- junit整合
- aop
- 動態代理實現
- cglib代理實現
- aop名詞
- spring的aop
- aop-xml詳解
- aop-注解詳解
- 代理方式選擇
- jdbcTemplate
- spring事務管理
- 回滾注意
- 事務傳播屬性
- MyBatis
- MyBatis簡介
- 入門程序
- 與jdbc hibernate不同
- 原始Dao開發
- Mapper動態代理方式
- SqlMapConfig.xml配置文件
- 輸入參數pojo包裝類
- resultMap
- 動態sql
- 一對一關聯
- 一對多
- 整合spring
- 逆向工程
- maven
- maven簡介
- 倉庫
- maven目錄結構
- maven常用命令
- 生命周期
- eclipse中maven插件
- 入門程序
- 整合struct
- 依賴范圍
- 添加插件
- idea配置
- jar包沖突
- 分模塊開發
- 構建可執行的jar包(包含依賴jar包)
- springMVC
- 處理流程
- java面試
- java版本升級
- java1-8版本變更
- java9新特性
- 鎖
- java資料
- idea
- jdk版本切換
- log4j
- 入門實例
- 基本使用方法
- Web中使用Log4j
- spring中使用log4j
- java代碼優化