直到今天,我还以为:
i += j;
只是一个捷径:
i = i + j;
但是如果我们尝试这个怎么办:
int i = 5;
long j = 8;
然后 i = i + j;
不会编译但是 i += j;
将编译好。
实际上这是否意味着什么? i += j;
这是这样的捷径
i = (type of i) (i + j)
?
直到今天,我还以为:
i += j;
只是一个捷径:
i = i + j;
但是如果我们尝试这个怎么办:
int i = 5;
long j = 8;
然后 i = i + j;
不会编译但是 i += j;
将编译好。
实际上这是否意味着什么? i += j;
这是这样的捷径
i = (type of i) (i + j)
?
和往常一样,JLS都有答案。在这种情况下 §15.26.2复合赋值运算符。提取物:
表单的复合赋值表达式
E1 op= E2
相当于E1 = (T)((E1) op (E2))
,哪里T
是的类型E1
, 除了那个E1
仅评估一次。
引用的一个例子 §15.26.2
[...]以下代码是正确的:
short x = 3; x += 4.6;
并且结果x的值为7,因为它相当于:
short x = 3; x = (short)(x + 4.6);
换句话说,你的假设是正确的。
这个演员的一个很好的例子是使用* =或/ =
byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57
要么
byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40
要么
char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'
要么
char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'
非常好的问题。该 Java语言规范 确认你的建议。
例如,以下代码是正确的:
short x = 3; x += 4.6;
并且结果x的值为7,因为它相当于:
short x = 3; x = (short)(x + 4.6);
是,
基本上我们写的时候
i += l;
编译器将其转换为
i = (int)(i + l);
我刚检查了一下 .class
文件代码。
真的是一件好事
你需要施放 long
至 int
explicitly
的情况下 i = i + l
然后它将编译并提供正确的输出。喜欢
i = i + (int)l;
要么
i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.
但是如果是的话 +=
它只是工作正常,因为运算符隐式执行从右变量类型到左变量类型的类型转换,因此无需显式转换。
这里的问题涉及类型铸造。
当你添加int和long时,
但 +=
以这样的方式编码,即它进行类型转换。 i=(int)(i+m)
在Java类型中,当赋值操作右侧的表达式类型可以安全地提升为赋值左侧的变量类型时,将自动执行转换。因此我们可以安全地分配:
byte - > short - > int - > long - > float - > double。
反之亦然。例如,我们不能自动将long转换为int,因为第一个需要比第二个更多的存储,因此信息可能会丢失。要强制执行此类转换,我们必须执行显式转换。
类型 - 转换
有时,在面试时可以提出这样的问题。
例如,当你写:
int a = 2;
long b = 3;
a = a + b;
没有自动类型转换。在C ++中,编译上面的代码不会有任何错误,但在Java中你会得到类似的东西 Incompatible type exception
。
所以要避免它,你必须编写如下代码:
int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting
主要区别在于 a = a + b
,没有进行类型转换,因此编译器因为没有进行类型转换而对你生气。但随着 a += b
,它真正做的是类型转换 b
与兼容的类型 a
。所以,如果你这样做
int a=5;
long b=10;
a+=b;
System.out.println(a);
你真正在做的是:
int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);