关于基本类型的简单赋值和复合赋值运算

转载 2012年03月23日 16:44:53

通过阅读下面转载的文章,Kaiwii学习到以下的内容:

1、需要判断一个变量的类型,可以采用下面的方式完成:

假如我要弄清楚2.0/SAMPLING_COUNT的结果的类型,Kaiwii可以这样做:

Object var=2.0/SAMPLING_COUNT;
System.out.println(var.getClass().getSimpleName());

2、可以通过查看和比较生成的class文件来判断两种写法的实际执行过程是否一样

3、自动提升类型和自动降低类型的理解:

在运算过程中,一般情况下会进行进行自动提升类型,也就是一个低精度的变量为了与高精度的变量进行运算而发生的低精度向高精度类型转换的过程。比如文中提到的:

short s1 = 1; s1 = s1 + 1; 

为什么不正确,是因为1是int类型的,所以S1与其发生运算的过程中会升级为int类型,所以最终生成的结果的类型应该是int的。一个int类型的变量怎么可以赋值到一个shor类型的变量中去呢?除非使用强制转换的方式吧……

另外,只有在直接将一个常量值赋值给一个变量的时候,才可能发生自动降低类型的情况。比如文中提到的情况:

short i=1

分析:1是int类型的常量,可以通过自动降低类型的方式赋值给一个更低精度的变量i

其中,比较特殊的自动降低类型的方式还包括:

short i+=1
好吧,Kaiwii说了那么废话,直接上原文吧……

有一道很经典的面试题是这样的:
short s1 = 1; s1 = s1 + 1; 有什么错? short s1 = 1; s1 += 1;有错吗?

答案很简单:
1. 编译出错。类型不匹配,需要强制类型转换。
2. 没有错误。

有一朋友说不是太明白这是为什么。我在这里分析一下原因。
对于前半部分:

Java代码 复制代码 收藏代码
  1. short s1 = 1; s1 = s1 + 1;

在java语言规范里,如果表达式中, 当对中间值的精确要求有时可能会超过任何一个操作数的范围, JVM会临时自动提升这个操作数的类型。
像我们这个题目的前面部分,s1 + 1, 我们把类型写出来s1(short) + 1(int)这时JVM会自动把s1先提升成int,然后再跟后面的1(int)相加,这样就是int + int的运算了。但是为什么会有编译错误呢?因为int + int的结果还是int。我们看一下这个例子:
Java代码 复制代码 收藏代码
  1. short s1 = 1;
  2. Object result = s1 + 1;
  3. System.out.println(result.getClass().getSimpleName());

结果是:
Integer

从结果可以看出,结果是int的包装类Integer。所以s1 + 1的结果是int类型的。因此把s1 + 1重新赋值给s1,即s1 = s1 + 1,会丢失精度,编译出错。

对于后半部分 s1 += 1,个人认为可以分为两部分,见下面代码:
Java代码 复制代码 收藏代码
  1. short s1 = 1;
  2. s1 = (short)((int) s1 + 1);

这样解释的原因可以再看下面的例子:
Java代码 复制代码 收藏代码
  1. public class Test {
  2. public void test1(){
  3. short s1 = 1;
  4. s1 = (short)((int) s1 + 1);
  5. }
  6. public void test2() {
  7. short s1 = 1;
  8. s1 += 1;
  9. }
  10. }

查看Test.class文件的字节码文件:
Java代码 复制代码 收藏代码
  1. public void test1();
  2. 0 iconst_1
  3. 1 istore_1 [s1]
  4. 2 iload_1 [s1]
  5. 3 iconst_1
  6. 4 iadd
  7. 5 i2s
  8. 6 istore_1 [s1]
  9. 7 return
  10. Line numbers:
  11. [pc: 0, line: 4]
  12. [pc: 2, line: 5]
  13. [pc: 7, line: 6]
  14. Local variable table:
  15. [pc: 0, pc: 8] local: this index: 0 type: Test
  16. [pc: 2, pc: 8] local: s1 index: 1 type: short
  17. public void test2();
  18. 0 iconst_1
  19. 1 istore_1 [s1]
  20. 2 iload_1 [s1]
  21. 3 iconst_1
  22. 4 iadd
  23. 5 i2s
  24. 6 istore_1 [s1]
  25. 7 return
  26. Line numbers:
  27. [pc: 0, line: 9]
  28. [pc: 2, line: 10]
  29. [pc: 7, line: 11]
  30. Local variable table:
  31. [pc: 0, pc: 8] local: this index: 0 type: Test
  32. [pc: 2, pc: 8] local: s1 index: 1 type: short

除了11-13行和28-30行的内的行号不同之外,其余部分都一样。即这两上写法其实是等效的。
s1 = (short)((int) s1 + 1); 可以简化为s1 = (short)(s1 + 1);因为从short到int JVM会自动提升类型。

最后补充一点,JVM会自动提升类型的表达式为:
Java代码 复制代码 收藏代码
  1. short +|-|*|/|% short = (int) short +|-|*|/|% (int) short;
  2. byte +|-|*|/|% byte = (int) byte +|-|*|/|% (int) byte;
  3. char +|-|*|/|% char = (int) char +|-|*|/|% (int) char;

因为这些类型的运算很容易就会越界。它们之间的任意组合都会先转换成int,然后再运算,结果为int类型。但是遇到更高精度的操作数,如float、double,它们也会向float、double自动提升类型。自动提升类型除基本赋值外,都是向精度高的方向进行的。
对于short、byte、char的基本赋值,就像short s1 = 1;是int类型自动降低类型到short的。 


java基本数据类型之间赋值与运算归纳

面对“byte b1=3;byteb2=7;byte b=b1+b2;”报错,而“int i1=3;int i2=7;int i=i1+i2;”不报错,进行了深入探究,从而引申出java基本类型之间赋...
  • u011331844
  • u011331844
  • 2014年03月03日 21:19
  • 2546

关于基本类型的简单赋值运算和复合赋值运算

原文网址:http://tianlihu.iteye.com/blog/376603 有一道很经典的面试题是这样的:  short s1 = 1; s1 = s1 + 1; 有什么错? short...
  • u010131960
  • u010131960
  • 2013年12月13日 23:19
  • 467

基本类型 引用类型 简单赋值 对象引用

原文地址:https://segmentfault.com/a/1190000002789651 ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型。也有其他的叫法,比如原始类型和对...
  • duandianyiwai
  • duandianyiwai
  • 2016年08月10日 09:52
  • 654

【java解惑】复合赋值与简单赋值

复合赋值操作符有:+=、-=、*=、/=、%=、 >=、 >>>=、&=、 ^=和| = ;    简单赋值操作符为= ;    如下所示代码:public class Example009 { ...
  • imu2008
  • imu2008
  • 2015年11月04日 08:41
  • 740

JavaScript中的基本类型和引用类型的赋值问题和传参问题

我们先来看一个基本类型的例子:var num1 = 5; var num2 = num1;上面的num1属于基本类型,把num1赋值给num2,相当于把num1的一个副本赋值给num2,num2中的5...
  • code_ja
  • code_ja
  • 2016年06月22日 16:07
  • 363

c语言:赋值运算符与赋值表达式

任务代码: #include int main () { int a printf("%d",(a=5)); return 0; } 执行情况: 知识总结: 运算符的优先...
  • Zzwtyds
  • Zzwtyds
  • 2016年09月27日 10:32
  • 1040

C++重载复合赋值运算符、算术运算符和关系运算符

原文链接:http://blog.csdn.net/lyh__521/article/details/49622601复合赋值运算符  形如‘*=’、‘+=’、‘/=’等这样的运算符称为复合赋值运算符...
  • lyh__521
  • lyh__521
  • 2015年11月03日 21:35
  • 1667

第五章 使用复合赋值和循环语句

5.1使用复合赋值操作符可将任何算术操作符与赋值操作符合并见下表。这些操作符称为复合赋值操作符。 操作符+=可用于字符串;作用是将一个字符串附加到另一个字符串末尾。例如,以下代码在控制台上显示”...
  • qq_28372083
  • qq_28372083
  • 2016年12月04日 16:39
  • 328

c语言算术运算表达式与赋值运算表达式的类型转换规则

一.算术表达式的类型转换规则 1.对于单精度实型操作数,系统先将表达式中所有单精度实型(float型)操作数(常量或变量)转换为双精度实型,在参与运算。 2.对于字符型操作数,系统先将表达式中所有...
  • nice_catch
  • nice_catch
  • 2016年08月11日 16:52
  • 1291

Java基础之运算符(算数运算符和赋值运算符)

Java的基础知识 运算符的操作
  • u011134899
  • u011134899
  • 2017年04月20日 22:47
  • 355
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于基本类型的简单赋值和复合赋值运算
举报原因:
原因补充:

(最多只允许输入30个字)