直到今天,我还以为:
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)?
当前回答
此处的微妙之处。。。
当j是double,i是int时,i+j有一个隐式类型转换。当整数之间有运算时,Java总是将整数转换为双精度。
为了澄清i+=j,其中i是整数,j是双精度,可以描述为
i = <int>(<double>i + j)
参见:隐式铸造的描述
为了清楚起见,在本例中可能需要将j类型转换为(int)。
其他回答
此处的微妙之处。。。
当j是double,i是int时,i+j有一个隐式类型转换。当整数之间有运算时,Java总是将整数转换为双精度。
为了澄清i+=j,其中i是整数,j是双精度,可以描述为
i = <int>(<double>i + j)
参见:隐式铸造的描述
为了清楚起见,在本例中可能需要将j类型转换为(int)。
在i=i+l的情况下,需要显式地从long转换为int,然后它将编译并给出正确的输出。喜欢
i = i + (int)l;
or
i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.
但在+=的情况下,它工作得很好,因为运算符隐式执行从右变量类型到左变量类型的类型转换,因此不需要显式转换。
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中引入的黑客无法删除。
这里的问题涉及类型转换。
当您添加int和long时,
int对象被强制转换为long,这两个对象都被添加,您将得到long对象。但long对象不能隐式转换为int。因此,必须显式转换。
但+=的编码方式使其可以进行类型转换。i=(int)(i+m)
Yes,
基本上当我们写作时
i += l;
编译器将其转换为
i = (int)(i + l);
我刚检查了.class文件代码。
知道这真是件好事