2017-10-21 90 views
10

我無法理解加法運算符或short數據類型的想法。Java +操作員

據說,

short a = 1; 
short b = 2; 
short c = a + b; 

這將不能編譯,因爲除了運營商總是投shortchartbyte數據類型,以int,我理解這一點。但是這個;

short c = 1 + 2; 

完全沒問題。因此,如果加法運算符自動將short轉換爲int,然後應用結果(其中結果的結果將是int),爲什麼這可以正常工作?

編輯:此問題與Primitive type 'short' - casting in Java不重複,因爲我瞭解轉換過程。另外,這個問題涉及數據類型的轉換,因爲我的問題涉及到文字。

+9

由於兩個操作數都是編譯時間常數,因此可以在編譯時計算「1 + 2」。換言之,'short c = 1 + 2;'將編譯爲'short c = 3;'。如果結果超出「短」範圍,您仍然會出錯。 – Pshemo

+0

@Pshemo那麼這意味着一個'int'會被明確地降低爲'short'?因爲1 + 2或者被解析爲'short'仍然會被評估爲'int',否? – dosdebug

+5

@dosdebug不,這裏沒有添加。它的編譯方式與'short c = 3'相同;' – Neo

回答

0

據我所知,Java支持+ int和long,但是按照規定,不能簡寫。沒有自動類型轉換,因爲該操作被指定爲在int或long數據類型上執行。

https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

如果你想獲得一個有效的結果,知道結果不會導致溢出,你可以把結果:

short a = 1; 
short b = 2; 
short c = (short)(a + b); 
6

1 + 2是一個常量表達式,而a + b不是。
它對評估它們很重要。
第一個將在編譯時完成,第二個在運行時完成。

JLS 8狀態:

15.28。常量表達式

常量表達式是一個表達式表示原始 類型或字符串的一個值,該值不會突然完成並僅使用 由下列:

原始類型和文字的
  • 字面String類型(§3.10.1, §3.10.2,§3.10.3,§3.10.4,§3.10.5)

  • 施放到原始類型並投射到串類型(§15.16)

  • 一元運算符+, - ,〜和! (但不是++或 - )(§15.15.3, §15.15.4,§15.15.5,§15.15.6)

  • 乘法運算符*,/,和%(§15.17)

  • 加法運算符+和 - (§15。18)

........................

這裏:

short c = 1 + 2; 

1 + 2是由兩個int文字和一個加法運算符組成。
所以它被認爲是一個常數表達式。
在編譯時評估常量表達式。
所以short c作爲3

這裏評估是一個示例類:

package stackoverflow; 

public class EvaluationClass { 

    public void foo(){ 
     short c = 1 + 2; 
    } 
} 

下面是反彙編代碼:

Compiled from "EvaluationClass.java" 
public class stackoverflow.EvaluationClass { 
    public stackoverflow.EvaluationClass(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":() 
     4: return 

    public void foo(); 
    Code: 
     0: iconst_3 
     1: istore_1 
     2: return 
} 

我們可以看到,裝載3int0: iconst_3指令堆棧。


鑑於此:

short a = 1; 
short b = 2; 
short c = a + b; 

a + b僅在運行時評價爲ab不是恆定值。
它們的值可能在任何時候都會改變。
請注意,如果ab有效變異,則編譯器不會試圖通過閱讀每個語句來猜測。
它認爲它只能在運行時評估a + b

現在在這種情況下,爲什麼a + b不會產生short而是int
由於JLS 8規定:

4.2.2。整數運算

如果比的變速操作者以外的整數操作者有long類型中的至少一個 操作數,則該操作被執行使用64位 精度,數值運算符的結果是類型長的。 如果另一個操作數不長,則首先擴展(§5.1.5),以便通過數字提升鍵入 (§5.6)。

否則,操作是使用32位精度進行的,並且 數值運算符的結果是int類型的結果。如果任一操作數 不是int,則首先將其擴展爲通過數字提升來鍵入int。


作爲一個側面說明,如果更改代碼,使abconstants

final short a = 1; 
final short b = 2; 
short c = a + b; 

這將現編譯罰款a + b將作爲一個常量表達式進行評估(3) 。

+0

謝謝。這已經回答了問題的評論。感謝您的額外寫作。 – dosdebug