直到今天,我还以为:
i += j;
只是一条捷径:
i = i + j;
但如果我们这样做:
int i = 5;
long j = 8;
则i=i+j;不会编译,但i+=j;将编译良好。
这是否意味着实际上i+=j;是这样的捷径吗i=(i的类型)(i+j)?
直到今天,我还以为:
i += j;
只是一条捷径:
i = i + j;
但如果我们这样做:
int i = 5;
long j = 8;
则i=i+j;不会编译,但i+=j;将编译良好。
这是否意味着实际上i+=j;是这样的捷径吗i=(i的类型)(i+j)?
当前回答
有时候,这样的问题可以在面试中提出。
例如,当您写:
int a = 2;
long b = 3;
a = a + b;
没有自动打字。在C++中,编译上述代码时不会出现任何错误,但在Java中,您会遇到类似“不兼容类型异常”的情况。
因此,为了避免这种情况,您必须像这样编写代码:
int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting
其他回答
对于这些问题,JLS一如既往地掌握着答案。在这种情况下,§15.26.2复合赋值运算符。摘录:
形式为E1 op=E2的复合赋值表达式等价于E1=(T)((E1)op(E2)),其中T是E1的类型,除了E1只计算一次。
§15.26.2中引用的示例
[…]以下代码正确:短x=3;x+=4.6;并且导致x具有值7,因为它等于:短x=3;x=(短)(x+4.6);
换句话说,你的假设是正确的。
在Java中,当赋值操作右侧的表达式类型可以安全地升级为赋值左侧的变量类型时,自动执行类型转换。因此,我们可以安全地分配:
byte -> short -> int -> long -> float -> double.
反之亦然。例如,我们不能自动将long转换为int,因为第一个比第二个需要更多的存储空间,因此信息可能会丢失。为了强制进行这样的转换,我们必须执行显式转换。类型-转换
很好的问题。Java语言规范证实了您的建议。
例如,以下代码是正确的:短x=3;x+=4.6;并且导致x具有值7,因为它等于:短x=3;x=(短)(x+4.6);
有时候,这样的问题可以在面试中提出。
例如,当您写:
int a = 2;
long b = 3;
a = a + b;
没有自动打字。在C++中,编译上述代码时不会出现任何错误,但在Java中,您会遇到类似“不兼容类型异常”的情况。
因此,为了避免这种情况,您必须像这样编写代码:
int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting
Java语言规范将E1 op=E2定义为等同于E1=(T)((E1)op(E2)),其中T是E1的一种类型。
这是一个技术性的答案,但你可能想知道为什么会这样。好吧,让我们考虑一下以下程序。
public class PlusEquals {
public static void main(String[] args) {
byte a = 1;
byte b = 2;
a = a + b;
System.out.println(a);
}
}
这个程序打印什么?
你猜到3了吗?太糟糕了,这个程序无法编译。为什么?好吧,在Java中,字节的加法被定义为返回int。我认为这是因为Java虚拟机没有定义字节操作来保存字节码(毕竟字节数有限),而使用整数操作是一种语言中公开的实现细节。
但如果a=a+b不起作用,这意味着如果它E1+=E2被定义为E1=E1+E2,a+=b将永远不会对字节起作用。如前一个示例所示,情况确实如此。作为一种使+=运算符适用于字节和短裤的方法,涉及到隐式转换。这不是一个很好的黑客,但在Java1.0工作期间,重点是从一开始就发布该语言。现在,由于向后兼容,这个在Java1.0中引入的黑客无法删除。