本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要下载到本机或重新发布到其它网站
有一道很经典的面试题是这样的:
short s1 = 1; s1 = s1 + 1; 有什么错? short s1 = 1; s1 += 1;有错吗?
答案很简单:
1. 编译出错。类型不匹配,需要强制类型转换。
2. 没有错误。
有一朋友说不是太明白这是为什么。我在这里分析一下原因。
对于前半部分:
short s1 = 1; s1 = s1 + 1;
在java语言规范里,如果表达式中, 当对中间值的精确要求有时可能会超过任何一个操作数的范围, JVM会临时自动提升这个操作数的类型。
像我们这个题目的前面部分,s1 + 1, 我们把类型写出来s1(short) + 1(int)这时JVM会自动把s1先提升成int,然后再跟后面的1(int)相加,这样就是int + int的运算了。但是为什么会有编译错误呢?因为int + int的结果还是int。我们看一下这个例子:
short s1 = 1;
Object result = s1 + 1;
System.out.println(result.getClass().getSimpleName());
结果是:
Integer
从结果可以看出,结果是int的包装类Integer。所以s1 + 1的结果是int类型的。因此把s1 + 1重新赋值给s1,即s1 = s1 + 1,会丢失精度,编译出错。
对于后半部分 s1 += 1,个人认为可以分为两部分,见下面代码:
short s1 = 1;
s1 = (short)((int) s1 + 1);
这样解释的原因可以再看下面的例子:
public class Test {
public void test1(){
short s1 = 1;
s1 = (short)((int) s1 + 1);
}
public void test2() {
short s1 = 1;
s1 += 1;
}
}
查看Test.class文件的字节码文件:
public void test1();
0 iconst_1
1 istore_1 [s1]
2 iload_1 [s1]
3 iconst_1
4 iadd
5 i2s
6 istore_1 [s1]
7 return
Line numbers:
[pc: 0, line: 4]
[pc: 2, line: 5]
[pc: 7, line: 6]
Local variable table:
[pc: 0, pc: 8] local: this index: 0 type: Test
[pc: 2, pc: 8] local: s1 index: 1 type: short
public void test2();
0 iconst_1
1 istore_1 [s1]
2 iload_1 [s1]
3 iconst_1
4 iadd
5 i2s
6 istore_1 [s1]
7 return
Line numbers:
[pc: 0, line: 9]
[pc: 2, line: 10]
[pc: 7, line: 11]
Local variable table:
[pc: 0, pc: 8] local: this index: 0 type: Test
[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会自动提升类型的表达式为:
short +|-|*|/|% short = (int) short +|-|*|/|% (int) short;
byte +|-|*|/|% byte = (int) byte +|-|*|/|% (int) byte;
char +|-|*|/|% char = (int) char +|-|*|/|% (int) char;
因为这些类型的运算很容易就会越界。它们之间的任意组合都会先转换成int,然后再运算,结果为int类型。但是遇到更高精度的操作数,如float、double,它们也会向float、double自动提升类型。自动提升类型除基本赋值外,都是向精度高的方向进行的。
对于short、byte、char的基本赋值,就像short s1 = 1;是int类型自动降低类型到short的。
分享到:
相关推荐
4. Pascal的复合数据类型:枚举、子界、数组和记录类型 5. 程序设计内容如下:使用记录数组来记录一个班学生的信息。学生信息包括:姓名、性别、年龄、民族(汉、蒙、满)、总成绩。输入一个班每人的信息,按照总...
用EBNF范式设计的一个简单的程序设计语言(语言中有+、-运算,语句有赋值语句、输入语句、输出语句、复合语句)
源语言要求至少包含的语言成分如下: 数据类型至少包括char类型、int类型和float类型 基本运算至少包括算术运算、比较运算、自增自减运算和复合赋值运算 控制语句至少包括if语句和while语句 实验内容:完整可运行的...
赋值运算符用来给变量赋值,Python提供的赋值运算符可分为简单赋值与复合赋值两大类。;关系运算符又称比较运算符,用于比较运算符两侧的值,比较的结果是一个布尔值,即True或False。;Python的逻辑运算符包括and(与...
然后,课程将深入探讨基本数据类型和运算,包括标识符、常量与变量的概念、基本数据类型中的整型、单精度实型、双精度实型、字符型常量和变量的定义与使用方法、算术运算符和算术表达式、赋值运算符和赋值表达式、...
* 熟练掌握C++表达式类型及求值规则(赋值运算、算术运算符和算术表达式、关系运算符和关系表达式、逻辑运算符和逻辑表达式、条件运算、指针运算、逗号表达式) 三、 C++的基本语句 * 掌握C++的基本语句,例如赋值...
在本章中,我们先介绍基本数据类型中的整型、浮点型和字符型。其余类型在以后各章中陆续介绍。 对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。在程序执行过程中,其值不发生改变的量称为常量,...
4.C表达式类型(赋值表达式、算术表达式、关系表达式、逻辑表达式、条件表达式、逗号表达式)和求值规则。 (三)基本语句 1.表达式语句,空语句,复合语句。 2.数据的输入与输出,输入输出函数的调用。 3.复合...
C++程序设计-谭浩强-清晰版完整书签 封面 -24 目录 -10 第1篇 基本知识 1 第1章 C++的初步知识 3 1.1 从C到C++ 3 ... 2.6.3 复合的赋值运算符 38 2.6.4 赋值表达式 39 2.7 逗号运算符与逗号表达式 40 习题 41
10.8 有关指针的数据类型和指针运算的小结 167 10.8.1 有关指针的数据类型的小结 167 10.8.2 指针运算的小结 167 10.8.3 void 指针类型 168 11 结构体与共用体 11.1 定义一个结构的一般形式 170 11.2 结构类型变量的...
10.8 有关指针的数据类型和指针运算的小结 167 10.8.1 有关指针的数据类型的小结 167 10.8.2 指针运算的小结 167 10.8.3 void 指针类型 168 11 结构体与共用体 11.1 定义一个结构的一般形式 170 11.2 结构类型变量的...
广东计算机水平考试二级《C++程序设计》考试大纲及样题 本考试大纲旨在考察学生对C++语言程序设计的基本知识和应用能力。考试内容涵盖了C++语言的基本...编程题分简单操作题、简单应用题和综合应用题3种类型的考题。
2.3.3 复合赋值语句 2.3.4 增值减值语句 2.3.5 复合语句 2.3.6 条件语句 2.3.7 循环语句 2.4 斐波纳契数 2.5 练习 第3章派生类型 3.1 常量和宏 3.2 枚举类型 3.3 数组 3.4 结构 3.5 ...
* 掌握 C++的自动类型转换和强制类型转换 主要考点: * 数据类型的种类 * 不同类型数据间的转换与运算 * 运算符的种类 * 运算符优先级和结合性 ㈡ 基本语句 * 了解 C 语句的概念及种类 * 掌握 C 语言常用的输入/...
4.C表达式类型(赋值表达式,算术表达式,关系表达式,逻辑表达式,条件表达式,逗号表达式)和求值规则。 三、基本语句 1.表达式语句,空语句,复合语句。 2.输入输出函数的调用,正确输入数据并正确设计...
4.C表达式类型(赋值表达式,算术表达式,关系表达式,逻辑表达式,条件表达式,逗号表达式)和求值规则。 三、基本语句 1.表达式语句,空语句,复合语句。 2.输入输出函数的调用,正确输入数据并正确设计...
1.2.2 最简单的C语言程序的基本结构 1.2.3 Dev C++ 1.3 printf()函数初步 1.3.1 简单的一般用法 1.3.2 特殊的字符 1.4 C语言的“字母”和“单词” 1.4.1 C语言的字母 1.4 12C语言的“词” 小结 概念与术语 风格与...
1. 基本要求 1数据类型:int,char 2语句:赋值(=),if,while,for;赋值 循环 条件判断 3算术运算:+,-,*,/,%,++,--,&,|,^,~,,>> 4关系运算:==,>,<,>=,,!= 5逻辑运算:&&(与),||(或),!...
第4章表达式和基本语句 4.1 运算符的优先级 4.2 复合表达式 4.3 if 语句 4.4 循环语句的效率 4.5 for 语句的循环控制变量 4.6 switch语句 4.7 goto语句 第5章常量 5.1 为什么需要常量 5.2 const 与 #define的比较 ...