真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java中自動(dòng)拆箱空指針異常如何解決

Java中自動(dòng)拆箱空指針異常如何解決,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

酒泉網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,酒泉網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為酒泉成百上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營(yíng)銷網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的酒泉做網(wǎng)站的公司定做!

問題重現(xiàn)

下面通過一個(gè)簡(jiǎn)單的示例才重現(xiàn)一下異常出現(xiàn)的場(chǎng)景。

public class BoxTest {

  public static void main(String[] args) {
    Map result = httpRequest();
    long userId = (Long) result.get("userId");
  }

  // 模擬一個(gè)HTTP請(qǐng)求
  private static Map httpRequest(){
    Map map = new HashMap<>();
    map.put("userId",null);
    return map;
  }
}

基本的場(chǎng)景就是請(qǐng)求一個(gè)接口,去接口中取某個(gè)值,這個(gè)值為L(zhǎng)ong類型,從Map中取得值之后,進(jìn)行Long類型的強(qiáng)轉(zhuǎn)。當(dāng)接口返回的userId為null時(shí),強(qiáng)轉(zhuǎn)這塊就拋出空指針異常:

Exception in thread "main" java.lang.NullPointerException at com.choupangxia.box.BoxTest.main(BoxTest.java:15)

上面的場(chǎng)景跟下面的代碼出現(xiàn)異常效果一樣:

public class BoxTest {

  public static long getValue(long value) {
    return value;
  }

  public static void main(String[] args) {
    Long value = null;
    getValue(value);
  }
}

上述代碼也是將Long類型進(jìn)拆箱導(dǎo)致的異常,只不過一個(gè)在代碼中,一個(gè)在參數(shù)中。為了分析更簡(jiǎn)化,我們以第二個(gè)為例進(jìn)行講解。

原因分析

最初大家可能會(huì)疑惑,拋出異常的代碼都沒有對(duì)象的方法調(diào)用,怎么會(huì)出現(xiàn)空指針呢? 這中間主要涉及到的就是一個(gè)自動(dòng)拆箱操作。是否是拆箱導(dǎo)致的呢?我們來通過字節(jié)碼看一下。

通過javap -c來查看一下對(duì)應(yīng)的字節(jié)碼:

public class com.choupangxia.box.BoxTest {
 public com.choupangxia.box.BoxTest();
  Code:
    0: aload_0
    1: invokespecial #1         // Method java/lang/Object."":()V
    4: return

 public static long getValue(long);
  Code:
    0: lload_0
    1: lreturn

 public static void main(java.lang.String[]);
  Code:
    0: aconst_null
    1: astore_1
    2: aload_1
    3: invokevirtual #2         // Method java/lang/Long.longValue:()J
    6: invokestatic #3         // Method getValue:(J)J
    9: pop2
   10: return
}

其中g(shù)etValue方法調(diào)用對(duì)應(yīng)的是main方法中編號(hào)3和6的操作。編號(hào)3為命令invokevirtual為方法指令。對(duì)應(yīng)的便是value.longValue,value對(duì)應(yīng)的就是聲明的Long類型。

也就是說編譯器將getValue(value)拆分成了兩步,第一步將通過value的longValue方法將其拆箱,然后再將拆箱之后的結(jié)果傳遞給方法。相當(dāng)于:

long primitive = value.longValue();
test(promitive);

對(duì)照最開始的代碼,如果value為null的話,那么在調(diào)用longValue方法時(shí)便會(huì)拋出NullPointerException.

所以,本質(zhì)上來講,所謂的自動(dòng)拆箱和裝箱只不過是Java提供的語法糖而已。

再次證實(shí)

下面用int類型的實(shí)例同時(shí)證實(shí)一下自動(dòng)拆箱和自動(dòng)裝箱兩個(gè)操作語法糖底層到底是怎么運(yùn)行的:

public class IntBoxTest {

  public static void main(String[] args) {
    Integer index = 11;
    int primitive = index;
  }
}

同樣查看上面代碼的字節(jié)碼:

public class com.choupangxia.box.IntBoxTest {
 public com.choupangxia.box.IntBoxTest();
  Code:
    0: aload_0
    1: invokespecial #1         // Method java/lang/Object."":()V
    4: return

 public static void main(java.lang.String[]);
  Code:
    0: bipush    11
    2: invokestatic #2         // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    5: astore_1
    6: aload_1
    7: invokevirtual #3         // Method java/lang/Integer.intValue:()I
   10: istore_2
   11: return
}

可以看到main方法部分,編號(hào)2進(jìn)行了裝箱操作,將原始類型int,裝箱成了Integer,調(diào)用的方法為Integer.valueOf;而編號(hào)7進(jìn)行了拆箱操作將Integer類型轉(zhuǎn)換成了int類型,調(diào)用的方法為Integer.intValue。

自動(dòng)拆箱裝箱的本質(zhì)

通過上面的分析,我們可以看出所謂的拆箱(unboxing)和裝箱(boxing)操作只不過是一個(gè)語法糖的功能。編譯器在編譯操作時(shí),本質(zhì)上還是會(huì)調(diào)用對(duì)應(yīng)包裝類的不同方法來進(jìn)行處理。

裝箱時(shí)通常會(huì)調(diào)用包裝類的valueOf方法,而拆箱時(shí)通常會(huì)調(diào)用包裝類的xxxValue()方法,其中xxx為類似boolean/long/int等。

而自動(dòng)拆箱和裝箱的操作主要發(fā)生在賦值、比較、算數(shù)運(yùn)算、方法調(diào)用等常見。此時(shí),我們就需要主要空指針的問題。

面試題

看一個(gè)面試題:請(qǐng)問下面foo1和foo2被調(diào)用時(shí)如何執(zhí)行?并簡(jiǎn)單分析一下。

public void foo1() {
  if ((Integer) null == 1) {
  }
}

public void foo2() {
  if ((Integer) null > 1) {
    System.out.println("abc");
  }
}

很明顯在調(diào)用兩個(gè)方法時(shí)都會(huì)拋出空指針異常。關(guān)于拋空指針異常的原因及分析過程,上文已經(jīng)講過,大家可以嘗試分析一下字節(jié)碼。

再看一個(gè)面試題:下面的語句能正常執(zhí)行嗎?

Integer value1 = (Integer) null;
Double value2 = (Double) null;
Boolean value3 = (Boolean) null;

看完上述內(nèi)容,你們掌握J(rèn)ava中自動(dòng)拆箱空指針異常如何解決的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


標(biāo)題名稱:Java中自動(dòng)拆箱空指針異常如何解決
地址分享:http://weahome.cn/article/ipcjie.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部