一文理解class.getClassLoader().getResourceAsStream(file)和class.getResourceAsStream(file)區別
基礎理解
都是實現獲取在classpath路徑下的資原始檔的輸入流。
為什麼是classpath而不是src,因為當web專案執行時,IDE編譯器會把src下的一些資原始檔移至WEB-INF/classes,classPath目錄其實就是這個classes目錄。這個目錄下放的一般是web專案執行時的class檔案、資原始檔(xml,properties...);
另外,在使用springboot進行開發時,其目錄預設不是WEB-INF而是BOOT-INF,但是其含義是一樣的。具體如下圖所示:
上圖,藍框中即為classpath中的內容,也就是自己實際編寫的程式碼,另外以來的程式碼主要再lib目錄下。從另外一個視角對比下,編譯前後檔案所在目錄的變化
編譯前:
編譯後:
class是獲取當前類的class物件,getClassLoader()是獲取當前的類載入器,什麼是類載入器?簡單點說,就是用來載入java類的,類載入器就是負責把class檔案載入進記憶體中,並建立一個java.lang.Class類的一個例項,也就是class物件,並且每個類的類載入器都不相同.getResourceAsStream(path)是用來獲取資源的,因為這是ClassLoader(類載入器)了獲取資源,而類載入器預設是從classPath下獲取資源的,因為這下面有class檔案.所以這段程式碼總的意思是通過類載入器在classPath目錄下獲取資源.並且是以流的形式。我們知道在Java中所有的類都是通過載入器載入到虛擬機器中的,而且類載入器之間存在父子關係,就是子知道父,父不知道子,這樣不同的子載入的型別之間是無法訪問的(雖然它們都被放在方法區中),所以在這裡通過當前類的載入器來載入資源也就是保證是和類型別同一個載入器載入的。
不同點
class.getClassLoader().getResourceAsStream(String name)
預設從classpath中找檔案(檔案放在resources目錄下),name不能帶“/”,否則會拋空指標
eg:
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("/gamvanclub.cfg.xml");
class.getResourceAsStream(String name)
查詢資源通過給定名稱,查詢資源的規則與給定的類的class load來實現,這個方法由類的loader來執行,如果這個類由bootstrap載入,那麼方法由ClassLoader.getSystemResourceAsStream代理執行。
代理之前,絕對的資源名稱通過傳入的name引數以下演算法進行構造:
如果name以"/"開頭,那麼絕對路徑是/後邊跟的名字
eg:
//從classpath下的config相對路徑中讀取config.ini"
mypackage.Hello.class.getResourceAsStream("/config/config.ini");
如果name不是以"/"開頭,那麼絕對路徑是package名"."換成“/”以後再加name。
eg:
//com.abc.App就是/com/abc/App/name 或者寫作 : ../../name(以class所在路徑為基準,檔案相對於該類的路徑)
Java類載入過程
3個步驟:
1.載入,載入類的二進位制檔案。
2.連結:
(1)驗證,驗證位元組碼的結構是否正確
(2)準備,給靜態成員分配空間並賦予預設值(注意這裡:靜態變數的第一次賦值是在類載入的時候就進行了,與後面初始化的時候的自定義賦值不是同一過程,也就是靜態成員在初始化的時候可能已被賦值二次了)
(3)解析,將符號引用變為直接引用
3初始化,為靜態成員賦予自己給定的初值
類的例項化的順序:
(1)靜態成員、方法與靜態程式碼塊的初始化與執行
(2)普通成員、方法與普通程式碼塊的初始化與執行
(3)建構函式的執行(父類的建構函式先執行)
相關文章
- 一文搞懂 $_POST 和 file_get_contents ("PHP://input") 的區別PHP
- v$datafile.file#與v$tempfile.file#區別
- java.io.File中mkdir()和mkdirs()區別Java
- 等待事件db file sequential read、db file scattered read和direct read的區別事件
- Oracle Password File 理解Oracle
- class與classloader的getResourceAsStream區別
- log file sync 和 log file parallel writeParallel
- Shell重定向&>file、2>&1、1>&2的區別
- alter database drop datafile 與 drop tablespace file 的區別Database
- Java學習之File類理解Java
- include "head_file" 和 include <head_file>
- alter system switch log file 與 archive log current/all 區別Hive
- File、Blob、ArrayBuffer等檔案類的物件有什麼區別和聯絡物件
- pg_file_settings和pg_settings系統檢視的區別
- ASM file和file alias之間的對映關係!ASM
- data file int write和db file sequential read個人想法
- php -- 取路徑:getcwd()、__DIR__、__FILE__ 的區別PHP
- utl_file.file_type使用
- File
- redo的等待log file sync和log file parallel write和redo size設定Parallel
- file_get_contents和fread的效能差別
- 【區別】“UTL_FILE_DIR引數” VS “DIRECTORY資料庫物件”資料庫物件
- Oracle db file parallel write 和 log file parallel write 等待事件 說明OracleParallel事件
- <input type="file"> 限制檔案型別型別
- db_file_name_convert和log_file_name_convert詳解
- jQuery :filejQuery
- Bat FileBAT
- docker fileDocker
- file_get_contents和fsockopen
- Java IO1:IO和FileJava
- SQL SERVER – Attach mdf file without ldf file in DatabaseSQLServerDatabase
- File雜談——初識file控制元件控制元件
- 個人理解Vue和React區別VueReact
- 表示一個檔案的 File 型別型別
- 0322理解db file parallel read等待事件2Parallel事件
- 0316理解db file parallel read等待事件Parallel事件
- 一文讀懂BeanFactory和FactoryBean區別Bean
- How to Convert Class File to Java File Online?Java