日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

自动装箱,拆箱和NoSuchMethodError

發布時間:2023/12/3 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自动装箱,拆箱和NoSuchMethodError 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

J2SE 5為Java編程語言引入了許多功能。 這些功能之一是自動裝箱和拆箱 ,這是我幾乎每天都沒有考慮過的功能。 它通常很方便(尤其是與收藏夾一起使用時),但有時會導致一些令人討厭的驚喜 ,即“ 怪異 ”和“ 瘋狂” 。 在此博客文章中,我介紹了一種罕見的NoSuchMethodError案例(但對我來說很有趣),該案例是由于在自動裝箱/拆箱之前將使用Java版本編譯的類與包含自動裝箱/取消裝箱的Java版本編譯的類混合在一起而造成的。

下一個代碼清單顯示了一個簡單的Sum類,該類可以在J2SE 5之前編寫。它已重載了“ add”方法,這些方法接受不同的原始數值數據類型,并且Sum>每個實例Sum>簡單地添加了通過以下任何一種方式提供給它的所有數字類型其重載的“添加”方法。

Sum.java(J2SE 5之前的版本)

import java.util.ArrayList;public class Sum {private double sum = 0;public void add(short newShort){sum += newShort;}public void add(int newInteger){sum += newInteger;}public void add(long newLong){sum += newLong;}public void add(float newFloat){sum += newFloat;}public void add(double newDouble){sum += newDouble;}public String toString(){return String.valueOf(sum);} }

在無法進行拆箱之前,上述Sum類的所有客戶端都需要向這些“添加”方法提供原語,或者,如果它們具有與原語相同的引用,則需要在將其中一個引用稱為“添加”方法。 在調用這些方法之前,在客戶端代碼上有責任從引用類型轉換為相應的原始類型。 下一個代碼清單中顯示了如何完成此操作的示例。

不取消裝箱:客戶端將引用轉換為基元

private static String sumReferences(final Long longValue, final Integer intValue, final Short shortValue) {final Sum sum = new Sum();if (longValue != null){sum.add(longValue.longValue());}if (intValue != null){sum.add(intValue.intValue());}if (shortValue != null){sum.add(shortValue.shortValue());}return sum.toString(); }

J2SE 5的自動裝箱和拆箱功能旨在解決這種情況下所需的額外工作 。 通過取消裝箱,客戶端代碼可以使用與預期的基本類型相對應的引用類型來調用上述“添加”方法,并且這些引用將自動“取消裝箱”為原始形式,以便可以調用適當的“添加”方法。 Java語言規范的 第5.1.8節 (“取消裝箱轉換”)說明了提供的數字引用類型在取消裝箱中將轉換為哪些原語,該規范的 第5.1.7節 (“裝箱轉換”)列出了自動裝箱的引用類型。從自動裝箱中的每個原語。

在此示例中,在調用Sum的“ add”方法之前,將引用類型轉換為對應的原始對等類型,從而使客戶方面的拆箱工作減少了,但并沒有使客戶完全不必在提供它們之前處理數字值。 因為引用類型可以為null ,所以客戶端可以為Sum的“ add”方法之一提供null引用,并且當Java嘗試自動將null取消裝箱到其對應的原語時,將引發NullPointerException 。 下一個代碼清單從上面進行了改編,以指示在客戶端不再需要將引用轉換為原語,但是仍然需要檢查null以避免NullPointerException 。

自動取消裝箱秘密對原始的引用:仍然必須檢查是否為空

private static String sumReferences(final Long longValue, final Integer intValue, final Short shortValue) {final Sum sum = new Sum();if (longValue != null){sum.add(longValue);}if (intValue != null){sum.add(intValue);}if (shortValue != null){sum.add(shortValue);}return sum.toString(); }

在設計API時,可能需要避免客戶端代碼在Sum上調用“ add”方法之前檢查其引用是否為null。 消除需求的一種方法是更改??“添加”方法以顯式接受引用類型,而不是原始類型。 然后, Sum類可以在顯式或隱式(取消裝箱)對它進行解引用之前檢查null。 接下來顯示了經過修改的Sum類,其中包含已更改的,更易于客戶端使用的API。

用“ add”方法求和的類期望引用而不是基元

import java.util.ArrayList;public class Sum {private double sum = 0;public void add(Short newShort){if (newShort != null){sum += newShort;}}public void add(Integer newInteger){if (newInteger != null){sum += newInteger;}}public void add(Long newLong){if (newLong != null){sum += newLong;}}public void add(Float newFloat){if (newFloat != null){sum += newFloat;}}public void add(Double newDouble){if (newDouble != null){sum += newDouble;}}public String toString(){return String.valueOf(sum);} }

修改后的Sum類對客戶端更友好,因為它允許客戶端將引用傳遞給它的任何“ add”方法,而不必擔心傳入的引用是否為null。 但是,如果涉及的任何一個類(客戶端類或Sum類的一個版本)都使用不同版本的Java編譯,則像這樣對Sum類的API進行更改可能會導致NoSuchMethodError 。 特別是,如果客戶端代碼使用原語并且使用JDK 1.4或更早版本進行編譯,并且Sum類是所示的最新版本(期望使用引用代替原語)并且使用J2SE 5或更高版本進行了編譯,則將遇到類似以下內容的NoSuchMethodError (“ S”表示它是“ add”方法,它期望原始short ,而“ V”表示該方法返回void )。

Exception in thread "main" java.lang.NoSuchMethodError: Sum.add(S)Vat Main.main(Main.java:9)

另一方面,如果客戶端使用J2SE 5或更高版本進行編譯,并且如第一個示例中那樣將原始值提供給Sum (預拆箱),并且Sum類在JDK 1.4或更早版本中使用“ add”方法進行編譯原語,會遇到不同版本的NoSuchMethodError 。 請注意,此處引用了Short參考。

Exception in thread "main" java.lang.NoSuchMethodError: Sum.add(Ljava/lang/Short;)Vat Main.main(Main.java:9)

由此可見對Java開發人員的一些觀察和提醒。

  • 類路徑很重要:
    • 使用相同版本的Java(相同的-source和-target )編譯的Java .class文件可以避免本文中的特定問題。
  • 自動裝箱和取消裝箱的目的是很好的,并且通常非常方便,但是如果在一定程度上不牢記,可能會導致令人驚訝的問題。 在這篇文章中,仍然需要檢查空值(或知道對象不是空值),這是由于拆箱而導致隱式解引用的情況。
  • 是否允許客戶端傳遞null并讓服務類代表它們檢查null是API風格的問題。 在工業應用程序中,我將用每個方法的Javadoc注釋中的@param聲明每個“添加”方法參數是否允許為null。 在其他情況下,可能要讓調用者負責確保任何傳入的引用都不為空,并且如果調用者不遵守該約定,則拋出NullPointerException內容將是滿意的(也應在方法的Javadoc)。
  • 盡管通常會在完全刪除某個方法或在該方法可用之前訪問舊類或方法的API在類型或類型數方面發生更改時看到NoSuchMethodError 。 在Java自動裝箱和拆箱在很大程度上被視為理所當然的日子里,很容易想到將方法從采用原語轉換為采用相應的引用類型不會產生任何影響,但是即使這種更改也會導致異常,如果并非所有涉及的類都基于支持自動裝箱和拆箱的Java版本構建。
  • 確定要針對其編譯特定.class文件的Java版本的一種方法是使用javap -verbose并在javap輸出中查找“主要版本:”。 在本文示例中使用的類(針對JDK 1.4和Java SE 8編譯)中,“ 主要版本 ”條目分別為48和52( Java類文件上Wikipedia條目的“ 常規布局”部分列出了主要版本) )。

幸運的是,由于構建通常會清理所有工件并在相對連續的基礎上重建代碼,因此本文中使用示例和文本演示的問題并不常見。 但是,在某些情況下可能會發生這種情況,最可能的情況之一是意外使用舊的JAR文件時,因為它位于運行時類路徑上的等待中。

翻譯自: https://www.javacodegeeks.com/2014/08/autoboxing-unboxing-and-nosuchmethoderror.html

總結

以上是生活随笔為你收集整理的自动装箱,拆箱和NoSuchMethodError的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。