Java + 运营商
Java + Operator
我无法理解加法运算符或 short
数据类型的概念。
据说是这样;
short a = 1;
short b = 2;
short c = a + b;
不会编译,因为加法运算符总是将 short
、chart
、byte
数据类型转换为 int
,我理解这一点。但是这个;
short c = 1 + 2;
工作得很好。因此,如果加法运算符自动将 short
转换为 int
,然后应用结果(当然,结果将是 int
),为什么这样可以正常工作?
编辑: 这个问题与 Primitive type 'short' - casting in Java 不重复,因为我了解转换过程。另外,这个问题谈到了数据类型的转换,因为我的问题与 int
文字有关。
据我了解,Java 支持 int 和 long 的 +,但按照规定,不支持 short。没有自动类型转换,因为该操作被指定为对 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);
1 + 2
是常量表达式,而 a + b
不是。
这关系到他们的评价。
第一个会在编译时完成,第二个会在运行时完成。
JLS 8 状态:
15.28. Constant Expressions
A constant expression is an expression denoting a value of primitive
type or a String that does not complete abruptly and is composed using
only the following:
Literals of primitive type and literals of type String (§3.10.1,
§3.10.2, §3.10.3, §3.10.4, §3.10.5)
Casts to primitive types and casts to type String (§15.16)
The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3,
§15.15.4, §15.15.5, §15.15.6)
The multiplicative operators *, /, and % (§15.17)
The additive operators + and - (§15.18)
........................
这里:
short c = 1 + 2;
1 + 2
由两个int
文字和一个加法运算符组成。
所以它被认为是一个常量表达式。
常量表达式在编译时求值。
所以 short c
被评估为 3
这是一个示例 class :
package Whosebug;
public class EvaluationClass {
public void foo(){
short c = 1 + 2;
}
}
这里是反汇编代码:
Compiled from "EvaluationClass.java"
public class Whosebug.EvaluationClass {
public Whosebug.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
}
我们可以看到 0: iconst_3
指令将 3
int
加载到堆栈上。
而这里:
short a = 1;
short b = 2;
short c = a + b;
a + b
仅在运行时计算,因为 a
和 b
不是常量值。
他们的价值观确实随时都可能改变。
请注意,编译器不会试图通过阅读每个语句来猜测 a
和 b
是否有效变异。
它认为它可能因此仅在运行时评估 a + b
。
现在在这种情况下,为什么 a + b
不产生 short
而产生 int
?
因为 JLS 8 指定 :
4.2.2. Integer Operations
If an integer operator other than a shift operator has at least one
operand of type long, then the operation is carried out using 64-bit
precision, and the result of the numerical operator is of type long.
If the other operand is not long, it is first widened (§5.1.5) to type
long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and
the result of the numerical operator is of type int. If either operand
is not an int, it is first widened to type int by numeric promotion.
附带说明一下,如果将代码更改为 a
和 b
constants
:
final short a = 1;
final short b = 2;
short c = a + b;
现在可以正常编译,因为 a + b
将被评估为常量表达式 (3
)。
我无法理解加法运算符或 short
数据类型的概念。
据说是这样;
short a = 1;
short b = 2;
short c = a + b;
不会编译,因为加法运算符总是将 short
、chart
、byte
数据类型转换为 int
,我理解这一点。但是这个;
short c = 1 + 2;
工作得很好。因此,如果加法运算符自动将 short
转换为 int
,然后应用结果(当然,结果将是 int
),为什么这样可以正常工作?
编辑: 这个问题与 Primitive type 'short' - casting in Java 不重复,因为我了解转换过程。另外,这个问题谈到了数据类型的转换,因为我的问题与 int
文字有关。
据我了解,Java 支持 int 和 long 的 +,但按照规定,不支持 short。没有自动类型转换,因为该操作被指定为对 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);
1 + 2
是常量表达式,而 a + b
不是。
这关系到他们的评价。
第一个会在编译时完成,第二个会在运行时完成。
JLS 8 状态:
15.28. Constant Expressions
A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:
Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)
Casts to primitive types and casts to type String (§15.16)
The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)
The multiplicative operators *, /, and % (§15.17)
The additive operators + and - (§15.18)
........................
这里:
short c = 1 + 2;
1 + 2
由两个int
文字和一个加法运算符组成。
所以它被认为是一个常量表达式。
常量表达式在编译时求值。
所以 short c
被评估为 3
这是一个示例 class :
package Whosebug;
public class EvaluationClass {
public void foo(){
short c = 1 + 2;
}
}
这里是反汇编代码:
Compiled from "EvaluationClass.java"
public class Whosebug.EvaluationClass {
public Whosebug.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
}
我们可以看到 0: iconst_3
指令将 3
int
加载到堆栈上。
而这里:
short a = 1;
short b = 2;
short c = a + b;
a + b
仅在运行时计算,因为 a
和 b
不是常量值。
他们的价值观确实随时都可能改变。
请注意,编译器不会试图通过阅读每个语句来猜测 a
和 b
是否有效变异。
它认为它可能因此仅在运行时评估 a + b
。
现在在这种情况下,为什么 a + b
不产生 short
而产生 int
?
因为 JLS 8 指定 :
4.2.2. Integer Operations
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).
Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.
附带说明一下,如果将代码更改为 a
和 b
constants
:
final short a = 1;
final short b = 2;
short c = a + b;
现在可以正常编译,因为 a + b
将被评估为常量表达式 (3
)。