最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Gradle項目中的資源正確獲取方式

 更新時間:2020年11月21日 09:45:15   作者:Allocator  
這篇文章主要介紹了Java Gradle項目中的資源正確獲取方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

引言

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

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

兩個getResource方法

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

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

所有的資源都會存儲在resources文件夾內(nèi)部. 當(dāng)程序運行時獲取的資源就是這個resources文件夾下的資源.

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

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

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. 傳遞的參數(shù)有一個重要的注意事項, 就是傳遞的參數(shù)不能夠以/ 開始, 這也是我為什么稱呼這個參數(shù)為資源的相路徑. 舉個例子

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

運行上述代碼返回的結(jié)果是:

參考simpleresource的項目結(jié)構(gòu), 正確獲取 com.mainres 下的文件的正確做法是:

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

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

結(jié)果為:

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

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

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

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

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

String name = "";

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

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

再看 Class 中的 getResurce 方法

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

首先看傳遞參數(shù)為 "" 和 / 的兩種情況得到的結(jié)果:

使用空字符串:

String name = "";

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

運行結(jié)果:

使用 /

String name = "/";

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

運行結(jié)果為:

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

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

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

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

運行結(jié)果:

所以綜上所述, 一個簡單的防止兩個方法傳遞參數(shù)搞混淆的記憶方式就是使用 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);
 }

本質(zhì)上講它也是調(diào)用ClassLoader 中的getResource 方法. 其中resolveName 這個方法對傳遞的參數(shù)做了轉(zhuǎn)換.

private String resolveName(String name) {
  if (name == null) {
   return name;
  }
  if (!name.startsWith("/")) {
   Class<?> 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;
 }

當(dāng)傳遞的參數(shù)帶有/ 時候, resolveName 會將/ 去除后的字符串返回, 最后調(diào)用ClassLoader 中的 getResource 方法.

小結(jié)

本文對比了一下Class 和 ClassLoader 中的getResource 方法的差異,如果單純從資源的獲取角度來看最終調(diào)用的都是ClassLoader 中的getResource 方法.

簡單記憶即是使用Class 的getResource 方法資源路徑需要加/ 而使用ClassLoader 中的getResource 方法則不需要加/.

以上這篇Java Gradle項目中的資源正確獲取方式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot + vue 實現(xiàn)遞歸生成多級菜單(實例代碼)

    springboot + vue 實現(xiàn)遞歸生成多級菜單(實例代碼)

    這篇文章主要介紹了springboot + vue 實現(xiàn)遞歸生成多級菜單,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • 在Java編程中定義方法

    在Java編程中定義方法

    這篇文章主要介紹了在Java編程中定義方法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • rabbitmq延遲隊列的使用方式

    rabbitmq延遲隊列的使用方式

    這篇文章主要介紹了rabbitmq延遲隊列的使用方式,使用rabbitmq的延時隊列插件,實現(xiàn)同一個隊列中有多個不同超時時間的消息,并按時間超時順序出隊,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2024-04-04
  • 新手場景Java線程相關(guān)問題及解決方案

    新手場景Java線程相關(guān)問題及解決方案

    這篇文章主要介紹了新手場景Java線程相關(guān)問題及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • Mybatis之動態(tài)sql標(biāo)簽的使用

    Mybatis之動態(tài)sql標(biāo)簽的使用

    這篇文章主要介紹了Mybatis之動態(tài)sql標(biāo)簽的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 詳解JVM 中的StringTable

    詳解JVM 中的StringTable

    這篇文章主要介紹了JVM 中的StringTable,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java SpringBoot啟動指定profile的8種方式詳解

    Java SpringBoot啟動指定profile的8種方式詳解

    這篇文章主要介紹了spring boot 如何指定profile啟動的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java線程的生命周期的詳解

    Java線程的生命周期的詳解

    這篇文章主要介紹了Java線程的生命周期的詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • Java中的LinkedBlockingQueue源碼解析

    Java中的LinkedBlockingQueue源碼解析

    這篇文章主要介紹了Java中的LinkedBlockingQueue源碼解析,LinkedBlockingQueue底層是一個鏈表(可以指定容量,默認(rèn)是Integer.MAX_VALUE),維持了兩把鎖,一把鎖用于入隊,一把鎖用于出隊,并且使用一個AtomicInterger類型的變量保證線程安全,需要的朋友可以參考下
    2023-12-12
  • 深入理解Spring事務(wù)及傳播機制之原理解析與實際應(yīng)用

    深入理解Spring事務(wù)及傳播機制之原理解析與實際應(yīng)用

    Spring事務(wù)管理機制提供了多種傳播行為,可以控制事務(wù)的范圍和隔離級別,保證數(shù)據(jù)一致性和完整性。在實際應(yīng)用中,需要根據(jù)具體業(yè)務(wù)場景選擇合適的傳播行為實現(xiàn)事務(wù)控制
    2023-04-04

最新評論

伽师县| 仙游县| 运城市| 沈阳市| 观塘区| 永宁县| 呼玛县| 嘉鱼县| 文山县| 汪清县| 越西县| 宁强县| 丰原市| 宁强县| 平原县| 亚东县| 蓬安县| 宁强县| 广灵县| 土默特左旗| 壶关县| 时尚| 北宁市| 湖北省| 城市| 宿州市| 绍兴市| 靖江市| 双流县| 盐城市| 马尔康县| 伊宁市| 平顶山市| 盐源县| 济源市| 七台河市| 鄂伦春自治旗| 洛宁县| 涟源市| 镇巴县| 青冈县|