簡體   English   中英

為什么這些代碼在Java 7而不是Java 8中有效?

[英]Why does this bit of code work in Java 7 and not Java 8?

我目前正在使用IDE Eclipse版本:Neon.2發行版(4.6.2)和版本java版本8更新131.在此代碼中,IDE發出錯誤 - “類型不匹配:無法從字節轉換為整數”:

Integer i = (byte) 10;

但是這個代碼在IDE Eclipse Version:Indigo Service Release 2和java Version 7中正確執行。在第8版java的擴展轉換機制中有什么實質性的改變,因為我不認為它與IDE版本有關?

這絕對不是JDK的問題,因為在使用javac編譯器的命令行中,代碼會同時使用JDK 7和JDK 8拋出相同的編譯器錯誤 -

error: incompatible types
Integer i = (byte) 10;
            ^

事實上,我有Eclipse Mars Release 4.5.0並且它給了我與JDK 7和8相同的編譯錯誤。我沒有更新的版本所以沒有測試那些,但如果它沒有拋出編譯錯誤任何使用JDK 7的版本都必須是該JDK版本的eclipse編譯器的bug。

只有在一次進行兩次轉換時,您的作業才有效

  1. byte擴展到int
  2. intInteger拳擊

顯然,較舊的Eclipse版本允許更改,而javac從未允許這樣做(我測試了Java 6到Java 9)。

為了找出正確的行為,我們參考了規范

5.2。 作業上下文

賦值上下文允許將表達式的值賦值(第15.26節)給變量; 必須將表達式的類型轉換為變量的類型。

賦值上下文允許使用以下之一:

  • 身份轉換(§5.1.1)
  • 擴展的原始轉換(第5.1.2節)
  • 擴大參考轉換(第5.1.5節)
  • 一個拳擊轉換(§5.1.7),可選地后跟一個加寬的引用轉換
  • 一個拆箱轉換(第5.1.8節),可選地后跟一個加寬的基元轉換。

請注意,我們需要的代碼組合不在列表中。 我們可以從該列表中得出以下內容應該有效:

Number i = (byte) 10;

這是從byteByte的裝箱轉換,然后是擴展的引用轉換為Number

要么

Byte b = 42;
int i = b;

這是從Bytebyte的拆箱轉換,然后是從byteint的擴展基元轉換。

由於(byte) 10是編譯時常量,我們還必須考慮

此外,如果表達式是byteshortcharint類型的常量表達式(第15.28節):

  • 如果變量的類型是byteshortchar ,則可以使用縮小的基元轉換,並且常量表達式的值可以在變量的類型中表示。
  • 如果變量的類型是:則可以使用縮小的基元轉換,然后進行裝箱轉換:
    • Byte和常量表達式的值可在類型byte表示。
    • Short和常量表達式的值可以在short類型中表示。
    • Character和常量表達式的值可在char類型中表示。

來自同一部分。

這允許一些有趣的組合,如

Character c = (byte)10;

要么

Byte b = 'x';

但沒有一個可變類型的Integer


如上所述,從byteInteger的轉換不在列表中,因此較舊的Eclipse版本允許它的事實可以被認為是在較新版本中已修復的錯誤。

接受該計划的是ecj中的錯誤362279 ,該錯誤已於 2011年修復。

PS:為什么還要調查古代版本中的錯誤? 您只缺少JDT / Core中的1419個錯誤修復程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM