91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在Java Gradle項目中怎么獲取資源

發布時間:2020-11-21 14:35:37 來源:億速云 閱讀:192 作者:Leah 欄目:開發技術

在Java Gradle項目中怎么獲取資源?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一個Java Gradle項目會涉及到資源的訪問. 一般情況下會將當前項目所需的資源文件全部放置于resources文件夾下, 無論是main文件下的source code 還是test文件夾下的test code.

都或多或少的涉及到獲取resources文件夾下的資源. 本文主要目的就是詳細的總結一下如何獲取resources文件夾下的資源.

兩個getResource方法

來看一個簡單的Java Gradle項目(稱呼其為simpleresource)的項目結構

在Java Gradle項目中怎么獲取資源

首先這個project執行build之后會在根目錄下創建一個out目錄, 這個目錄存放所有的編譯結果(class文件以及資源文件). 如上圖所示production文件夾對應的是source code而test文件夾對應的是test code.

所有的資源都會存儲在resources文件夾內部. 當程序運行時獲取的資源就是這個resources文件夾下的資源.

我們使用最多的獲取資源的方法有兩個 Class.getResource 和 ClassLoader.getResource 但是這兩個方法傳遞參數與結果不同, 下面詳細分析一下這兩個方法參數以及返回值.

先看 ClassLoader 中的 getResource 方法. 只需要獲取類加載器對象即可(獲取方式不再贅述). 先看這個方法的API文檔相關的描述:

Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. The name of a resource is a '/'-separated path name that identifies the resource.

This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.

從這個描述中可以得知提供資源的路徑(我理解的是相對路徑), 正常情況下該方法會返回資源完整的URL. 傳遞的參數有一個重要的注意事項, 就是傳遞的參數不能夠以/ 開始, 這也是我為什么稱呼這個參數為資源的相路徑. 舉個例子

URL test = this.getClass().getClassLoader().getResource("/");

運行上述代碼返回的結果是:

在Java Gradle項目中怎么獲取資源

參考simpleresource的項目結構, 正確獲取 com.mainres 下的文件的正確做法是:

String name = "com/mainres/testmain.txt";

URL test = this.getClass().getClassLoader().getResource(name);

結果為:

在Java Gradle項目中怎么獲取資源

如果在表示資源路徑的字符串中加上 / 那么獲取到的URL依然為null

String name = "/com/mainres/testmain.txt";

URL test = this.getClass().getClassLoader().getResource(name);

在Java Gradle項目中怎么獲取資源

宗上所述, 使用類加載器獲取資源的方式傳遞的參數為資源相對路徑(相對于resources文件夾的路徑), 既然是相對路徑自然參數 不能夠以 / 開始.

有一個問題需要注意, 當傳遞參數為空字符串的時候, 得到路徑其實是classes文件夾的絕對路徑, 但當傳遞一個正確的資源路徑相對字符串時, 得到路徑卻是resources文件夾下的資源路徑.

String name = "";

URL test = this.getClass().getClassLoader().getResource(name);

在Java Gradle項目中怎么獲取資源

我的理解是本質上是通過此方法獲取的其實類加載器加載的class字節碼目錄, 所以使用空字符串會看到實際輸出的是classes文件夾絕對路徑, 當傳遞正確的資源路徑的時候, 代碼層面做轉換, 轉而獲取與classes文件夾同級的resources文件夾下的資源.

再看 Class 中的 getResurce 方法

由于這個方法傳遞參數是否是以 / 開頭會產生不同的結果, 且使用這個方法也比較容易和 ClassLoader 中的 getResource 方法搞混淆, 所以本文多次強調傳遞的參數是否以 / 開始.

首先看傳遞參數為 "" 和 / 的兩種情況得到的結果:

使用空字符串:

String name = "";

URL test = this.getClass().getResource(name);

運行結果:

在Java Gradle項目中怎么獲取資源

使用 /

String name = "/";

URL test = this.getClass().getResource(name);

運行結果為:

在Java Gradle項目中怎么獲取資源

最大的區別是使用空字符串 "" 獲取的路徑是相對于包的目錄, 而使用 / 獲取的路徑是類加載器加載class文件的目錄, 這個和 ClassLoader 的 getResource 方法傳遞 "" 字符串的結果是一樣的. 所以如果要正確的獲取到資源文件,

那么使用 Class 的 getResource 方法如下:

String name = "/com/mainres/testmain.txt";

URL test = this.getClass().getResource(name);

運行結果:

在Java Gradle項目中怎么獲取資源

所以綜上所述, 一個簡單的防止兩個方法傳遞參數搞混淆的記憶方式就是使用 Class 的 getResource 方法需要加 / 而使用 ClassLoader 的 getResource 方法不要加 /.

其實參考 Class 類中的 getResource 方法:

 public java.net.URL getResource(String name) {
  name = resolveName(name);
  ClassLoader cl = getClassLoader0();
  if (cl==null) {
   // A system class.
   return ClassLoader.getSystemResource(name);
  }
  return cl.getResource(name);
 }

本質上講它也是調用ClassLoader 中的getResource 方法. 其中resolveName 這個方法對傳遞的參數做了轉換.

private String resolveName(String name) {
  if (name == null) {
   return name;
  }
  if (!name.startsWith("/")) {
   Class<&#63;> c = this;
   while (c.isArray()) {
    c = c.getComponentType();
   }
   String baseName = c.getName();
   int index = baseName.lastIndexOf('.');
   if (index != -1) {
    name = baseName.substring(0, index).replace('.', '/')
     +"/"+name;
   }
  } else {
   name = name.substring(1);
  }
  return name;
 }

當傳遞的參數帶有/ 時候, resolveName 會將/ 去除后的字符串返回, 最后調用ClassLoader 中的 getResource 方法.

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

冕宁县| 巩留县| 定安县| 如皋市| 务川| 中方县| 嘉定区| 门源| 山西省| 万宁市| 刚察县| 霍林郭勒市| 平泉县| 德清县| 万山特区| 库伦旗| 通州市| 平江县| 南岸区| 外汇| 军事| 嘉黎县| 金阳县| 桃源县| 郧西县| 建瓯市| 尚志市| 普兰县| 巫山县| 卢湾区| 房山区| 伊川县| 宁夏| 涟水县| 巴中市| 江都市| 苗栗市| 洪湖市| 葵青区| 鹤峰县| 尼玛县|