2017-10-21 91 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