直到今天,我还以为:
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 = (type of i) (i + j)
有时,在面试时可以提出这样的问题 .
例如,当你写:
int a = 2; long b = 3; a = a + b;
没有自动类型转换 . 在C中,编译上面的代码不会有任何错误,但在Java中你会得到像 Incompatible type exception 这样的东西 .
Incompatible type exception
所以要避免它,你必须编写如下代码:
int a = 2; long b = 3; a += b;// No compilation error or any exception due to the auto typecasting
非常好的问题 . Java Language specification确认了你的建议 .
例如,以下代码是正确的:short x = 3;x = 4.6;并且结果x的值为7,因为它相当于:short x = 3;x =(短)(x 4.6);
主要区别在于 a = a + b ,没有进行类型转换,因此编译器因为没有进行类型转换而对你生气 . 但是对于 a += b ,它真正做的是将 b 类型转换为与 a 兼容的类型 . 所以,如果你这样做
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);
和往常一样,JLS都有答案 . 在这种情况下§15.26.2 Compound Assignment Operators . 提取物:
E1 op = E2形式的复合赋值表达式等效于E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1仅被评估一次 .
引自§15.26.2的一个例子
[...]以下代码是正确的:短x = 3;x = 4.6;并且结果x的值为7,因为它相当于:short x = 3;x =(短)(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'
这里的问题涉及类型铸造 .
当你添加int和long时,
int对象被转换为long并且两者都被添加并且你获得了长对象 .
但长对象不能隐式转换为int . 所以,你必须明确地这样做 .
但 += 的编码方式是它可以进行类型转换 . i=(int)(i+m)
+=
i=(int)(i+m)
你需要在 i = i + l 的情况下从 long 转换为 int explicitly 然后它将编译并提供正确的输出 . 喜欢
i = i + l
long
int
explicitly
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.
但是在 += 的情况下它只是工作正常,因为运算符隐式地从右变量的类型到左变量的类型进行类型转换,因此不需要显式转换 .
是,
基本上我们写的时候
i += l;
编译器将其转换为
i = (int)(i + l);
我刚检查了 .class 文件代码 .
.class
真的是一件好事
这里的细微之处......
当 j 是double并且 i 是int时, i+j 有一个隐式的类型转换 . Java ALWAYS 在它们之间存在操作时将整数转换为double .
j
i
i+j
澄清 i+=j 其中 i 是一个整数而 j 是一个双精度可以描述为
i+=j
i = <int>(<double>i + j)
见:this description of implicit casting
在这种情况下,为了清楚起见,您可能希望将 j 强制转换为 (int) .
(int)
在Java类型中,当赋值操作右侧的表达式类型可以安全地提升为赋值左侧的变量类型时,将自动执行转换 . 因此我们可以安全地分配:
byte -> short -> int -> long -> float -> double.
反之亦然 . 例如,我们不能自动将long转换为int,因为第一个需要比第二个更多的存储,因此信息可能会丢失 . 要强制执行此类转换,我们必须执行显式转换 .Type - Conversion
10 回答
有时,在面试时可以提出这样的问题 .
例如,当你写:
没有自动类型转换 . 在C中,编译上面的代码不会有任何错误,但在Java中你会得到像
Incompatible type exception
这样的东西 .所以要避免它,你必须编写如下代码:
非常好的问题 . Java Language specification确认了你的建议 .
主要区别在于
a = a + b
,没有进行类型转换,因此编译器因为没有进行类型转换而对你生气 . 但是对于a += b
,它真正做的是将b
类型转换为与a
兼容的类型 . 所以,如果你这样做你真正在做的是:
和往常一样,JLS都有答案 . 在这种情况下§15.26.2 Compound Assignment Operators . 提取物:
引自§15.26.2的一个例子
换句话说,你的假设是正确的 .
这个演员的一个很好的例子是使用* =或/ =
要么
要么
要么
这里的问题涉及类型铸造 .
当你添加int和long时,
int对象被转换为long并且两者都被添加并且你获得了长对象 .
但长对象不能隐式转换为int . 所以,你必须明确地这样做 .
但
+=
的编码方式是它可以进行类型转换 .i=(int)(i+m)
你需要在
i = i + l
的情况下从long
转换为int
explicitly
然后它将编译并提供正确的输出 . 喜欢要么
但是在
+=
的情况下它只是工作正常,因为运算符隐式地从右变量的类型到左变量的类型进行类型转换,因此不需要显式转换 .是,
基本上我们写的时候
编译器将其转换为
我刚检查了
.class
文件代码 .真的是一件好事
这里的细微之处......
当
j
是double并且i
是int时,i+j
有一个隐式的类型转换 . Java ALWAYS 在它们之间存在操作时将整数转换为double .澄清
i+=j
其中i
是一个整数而j
是一个双精度可以描述为见:this description of implicit casting
在这种情况下,为了清楚起见,您可能希望将
j
强制转换为(int)
.在Java类型中,当赋值操作右侧的表达式类型可以安全地提升为赋值左侧的变量类型时,将自动执行转换 . 因此我们可以安全地分配:
反之亦然 . 例如,我们不能自动将long转换为int,因为第一个需要比第二个更多的存储,因此信息可能会丢失 . 要强制执行此类转换,我们必须执行显式转换 .
Type - Conversion