第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

意外地將 String 添加到 List<Integers>

意外地將 String 添加到 List<Integers>

阿波羅的戰(zhàn)車 2021-11-03 10:49:55
我不明白編譯器如何處理以下代碼,因?yàn)樗谖移诖e誤時輸出測試。List<Integer> b = new ArrayList<Integer>();List a = b;a.add("test");System.out.println(b.get(0));我希望有人能告訴我編譯器在執(zhí)行代碼時所經(jīng)歷的確切步驟,以便我能夠理解輸出。我目前的理解是:編譯器會在編譯時檢查支持參數(shù)類型的 add 方法是否存在于以add(Object e)作為其原始類型的List類中。但是,在運(yùn)行時,它嘗試從實(shí)際對象List<Integer>調(diào)用 add(Object e) ,它不包含此方法,因?yàn)閷?shí)際對象不是原始類型的,而是包含方法add(Integer e)。如果在實(shí)際對象List<Integer> 中沒有 add(Object e) 方法,它如何仍然以某種方式將字符串添加到整數(shù)列表中?
查看完整描述

2 回答

?
嗶嗶one

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個贊

你很接近。編譯時檢查所有結(jié)果:

a是類型List所以調(diào)用

a.add("test");

平底鍋。b是(編譯時)類型ArrayList<Integer>所以

b.get(0)

退房。請注意,僅針對變量的編譯時類型進(jìn)行檢查。當(dāng)編譯器看到a.add("test")知道通過變量引用的對象的運(yùn)行時間值a。一般來說,它真的不能(在理論計(jì)算機(jī)科學(xué)中有一個關(guān)于這個的結(jié)果),盡管控制流類型分析可以捕捉到很多這樣的事情。像 TypeScript 這樣的語言可以在編譯時做出驚人的事情。

現(xiàn)在您可能假設(shè)在運(yùn)行時可以檢查這些事情。唉,在 Java 中他們不能。Java 刪除了泛型類型。查找有關(guān) Java 類型擦除的文章以了解詳細(xì)信息。TL;DR 是List<Integer>編譯時的 aList在運(yùn)行時變?yōu)樵嫉摹VM 沒有辦法“具體化”泛型(盡管其他語言有?。┧援?dāng)引入泛型時,決定 Java 將刪除泛型類型。所以在運(yùn)行時,你的代碼沒有類型問題。

我們來看一下編譯后的代碼:

 0: new           #2                  // class java/util/ArrayList

   3: dup

   4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V

   7: astore_1

   8: aload_1

   9: astore_2

  10: aload_2

  11: ldc           #4                  // String test

  13: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z

  18: pop

  19: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;

  22: aload_1

  23: iconst_0

  24: invokeinterface #7,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;

  29: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V

  32: return

在這里您可以直接看到?jīng)]有運(yùn)行時類型檢查。因此,對您的問題的完整(但看似輕率)的答案是 Java 僅在編譯時根據(jù)變量的類型(在編譯時已知)檢查類型,但泛型類型參數(shù)會被刪除,并且代碼在沒有它們的情況下運(yùn)行。


查看完整回答
反對 回復(fù) 2021-11-03
?
拉丁的傳說

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個贊

令人驚訝的是,b.get(0)它沒有運(yùn)行時檢查。我們希望編譯器解釋的代碼具有以下含義:

System.out.println((Integer)b.get(0)); // throws CCE

事實(shí)上,如果我們要嘗試:

Integer str = b.get(0); // throws CCE

我們會得到一個運(yùn)行時ClassCastException。

事實(shí)上,我們甚至?xí)玫较嗤腻e誤切換printf代替println

System.out.printf(b.get(0)); // throws CCE

這有什么意義?

由于向后兼容,這是一個無法修復(fù)的錯誤。如果目標(biāo)上下文可以允許刪除檢查轉(zhuǎn)換,那么盡管更改了語義,它也會被忽略。在這種情況下,過載從println(Integer)變?yōu)?code>println(Object)。比這更糟糕的是,有一個println(char[])具有不同行為的過載!

無論如何,不要使用原始類型或稀有類型,不要重載來改變行為(如果你可以管理它,也不要重載),并在將優(yōu)化提交到無法修復(fù)的規(guī)范之前要非常小心。


查看完整回答
反對 回復(fù) 2021-11-03
  • 2 回答
  • 0 關(guān)注
  • 189 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號