最近碰到一个java基础方面的问题:
package com.jspsmart.upload;
public class Test {
public static void main(String[] args) {
short i = 1;
i += 1; // 无任何问题
i = i + 1; // 报错,编译不通过
}
}
就打开网页google下,发现一篇对这个问题比较详细的介绍如下
short i =1; i=i+1;
short i=1;i+=1;
这两有什么区别呢 ?
对两个容量不一样的数据类型的变量进行算术运算时,java会自动将小容量的变量进行精度提升,然后再进行运算,得到的结果类型是提升后的大容量的数据类型.如果将该结果赋值给小容量的数据类型的变量,则必须进行强制的类型转换,否则编译程序会报损失精度错.如楼主示例,用i来表示1:
short s1 = 1;
int i = 1;
首先,因为short类型是16位的,而int类型是32位的,在进行
(s1+i) 运算时,自动将s1提升到32位,然后与i相加,得到的结果是32位的,而此时
s1=s1+i; 必然报错,因为如果赋值成功,只是把低16位赋给了s1,这个虽然正是楼主想要的结果,但是编译程序却不能判定你的意图是什么.
执行强转:
s1=(short)(s1+i); 就没问题了.
s1+=i;能编译通过并得到正确结果,而 s1=s1+i; 却报错,是因为它们并不像楼主认为的那样是等价的,s1+=i的方式java会对i进行窄化转换,由编译程序自动执行.
java规范中说:
E1 op=E2 实际上等价于 : E1=(T)( (E1)op(E2) )
其中T是E1的数据类型.这种类型转换或者是一个恒等转换,或者是一个窄化转换.
这个说明java是一种强类型的语言,对数据类型的要求是非常严格的,否则会引起混乱.
下面解释一下三种类型转换:恒等转换(相同容量的两个数据类型之间的赋值);拓宽转换(小容量类型赋值给大容量类型);窄化转换(大容量赋值给小容量类型). 实际上,前两种转换都是编译程序自动执行的,而窄化转换则要求必须显式的执行.
上面说了一堆的理论,最重要的就是下面一句
E1 op=E2 实际上等价于 : E1=(T)( (E1)op(E2) )
最后打算用发编译工具来查看下是否正确
.java 文件
public class Test {
public static void main(String[] args) {
short i = 1;
i += 1; // 无任何问题
}
}
根据编译的class文件反编译出来的.java文件
public class Test
{
public static void main(String[] args)
{
short i = 1;
i = (short)(i + 1);
}
}
非常清楚知道原因了
分享到:
相关推荐
容易出错Error Prone 是 Java 的静态分析工具,可以在编译时捕获常见的编程错误。public class ShortSet { public static void main (String[] args) { Set<Short> s = new HashSet(); for (short i = 0; i ; i++) {...
public short method1(int a, int b)**{ return 0; } **正确答案**:AC **解析**: - **A**:这是一个正确的重写示例。子类中的方法签名完全匹配父类的方法签名,并且访问级别从受保护变为公共,这是允许的。返回...
**1.3 JRE与JDK的区别?** - **JRE (Java Runtime Environment)**:Java运行环境,包含了Java虚拟机(JVM)以及运行Java程序所需的类库。它是面向用户的,用户安装JRE就可以运行Java程序。 - **JDK (Java ...
j=i;那么 i==j 的结果依旧为 false。这是因为 NaN 是一个特殊的值,它不能用于比较操作。 3. Java 1.5 的自动装箱拆箱机制 Java 1.5 引入了自动装箱拆箱机制,该机制是编译时自动完成替换的。在装箱阶段,Java 会...
`与`short s1 = 1; s1 += 1;`的区别是什么? - **解答要点**: - `short s1 = 1; s1 = s1 + 1;`会导致编译错误,因为`s1 + 1`的结果自动提升为`int`类型,需要显式转换回`short`类型。 - `short s1 = 1; s1 += 1;`...
Error Prone是Java的静态分析工具,可在编译时捕获常见的编程错误。 public class ShortSet { public static void main ( String [] args ) { Set< Short> s = new HashSet<> (); for ( short i = 0 ; i <...
` 会产生编译错误,因为 `s1 + 1` 的结果会被自动提升为 `int` 类型,再赋值给 `short` 类型时需要显式转换。 - `short s1 = 1; s1 += 1;` 编译正确,因为 `+=` 运算符由 Java 特别处理,能够自动处理类型转换。 **...
在文档编写过程中,编写者通常会遇到一些问题,比如对LaTeX语法的理解,宏包的正确安装和使用,以及编译过程中的错误解决。这份文档的目标受众是LaTeX的新手用户,他们可以通过阅读这份指南来快速掌握LaTeX的基础...
`,由于`s1 + 1`运算时会自动提升表达式的类型至`int`,再赋值给`short`类型`s1`时会导致编译错误,因为需要显式地进行类型转换。 - 对于`short s1 = 1; s1 += 1;`,由于`+=`是Java语言规定的运算符,Java编译器会...
au3反编译源码 myAut2Exe - The Open Source AutoIT Script Decompiler 2.9 ======================================================== *New* full support for AutoIT v3.2.6++ :) ... mmh here's what I ...
`i++`先发生,`i`为0,所以`j`的第一次加法是0+1(`i`自增到1),然后`++i`使得`i`再次自增到2,所以`j`最终等于2。对于`k`,同样按照从左到右的顺序,`--i`使`i`减到0,然后加上`i--`(此时`i`仍然是0,但之后会减...
**libmad库详解与编译安装指南** libmad是一个开源的MPEG音频解码库,主要支持MPEG-1 Layer 1, 2以及MPEG-2 Audio编码格式。它以其高效、高质量的解码能力而闻名,常用于音频处理、播放器软件和其他多媒体应用中。...
`中,第2行和第3行都会导致编译错误,因为s1+1的结果是int型,不能直接赋值给short型变量。答案是B和C。 16. Java中的变量名是区分大小写的,`number`和`NuMbEr`代表不同的变量。 17. 命名规范对于编写清晰易读的...
s1=s1+1; 和 short s1=1; s1+=1; 的区别 - **解释**: - `short s1=1; s1=s1+1;`:在进行加法运算时,两个操作数会被提升为`int`类型,之后再强制转换回`short`类型。 - `short s1=1; s1+=1;`:使用复合赋值...
s1+1 运算结果是 int 型,需要强制转换类型;short s1 = 1; s1 += 1;可以正确编译,自动类型提升。 7. Java 有没有 goto? goto 是 java 中的保留字,现在没有在 java 中使用。 8. int 和 Integer 有什么区别? ...
当尝试将这个`int`类型的结果赋值给`short`类型的`s1`时,编译器会报错,提示需要进行类型转换。 对于`short s1 = 1; s1 += 1;`,因为`+=`是Java语言中预定义的运算符,编译器会自动进行类型转换处理,所以这条语句...
编译系统在对源程序进行编译时不理会注释部分,因此注释对于程序的功能实现不起任何作用。而且由于编译时忽略注释部分,所以注释内容不会增加最终产生的可执行程序的大小。适当地使用注释,能够提高程序的可读性。在...
`,由于表达式`s1 + 1`的结果会被自动提升为`int`类型,因此在将结果赋值给`short`类型时需要显式转换。 - 对于`short s1 = 1; s1 += 1;`,`+=`操作符会自动处理类型转换,因此可以直接使用。 ### `char`类型与...
`会导致编译错误,因为`s1 + 1`的结果会被提升为`int`类型,再次赋值给`short`类型的`s1`需要显式类型转换。 - `short s1 = 1; s1 += 1;`是正确的,因为`+=`运算符会被特殊处理,自动进行类型转换。 ### 7. `char`...
`会导致编译错误,因为`s1 + 1`的操作会导致类型提升至`int`类型,再赋值给`short`类型时需要显式转换。 - 而`short s1 = 1; s1 += 1;`是合法的,因为`+=`操作符会被特殊处理,确保正确的类型转换。 ### 7. `char`...