首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

一个简单而有趣的类型转换有关问题

2013-11-14 
一个简单而有趣的类型转换问题默认的整数值类型是int,默认的小数值类型是double。int a 56 //数值56默认

一个简单而有趣的类型转换问题
默认的整数值类型是int,默认的小数值类型是double。
int a = 56; //数值56默认为int类型
double d = 3.14; //数值3.14默认为double类型



下面问题来了:
float f = 3.14; //编译通过不了。因为无法将一个double类型的值赋给一个float类型的变量。

short s = 56; //编译可以通过。这是为什么呢?将一个int类型的值赋给一个short类型的变量不损失精度么?为什么可以通过编译呢?

但我还是有些疑问,你说56是个地道的常量,没有超出short范围,所以可以直接赋给short类型的变量对吧。那我想知道3.14是个地道的常量么?它超出float的范围了么?那它为什么不能直接赋给float类型的变量呢?你要是想说3.14默认是double类型的,高精度向低精度赋值要强制类型转换,那我就会继续问56默认是什么类型的?它为什么可以直接赋值给short类型的变量呢? 
我怎么总感觉整型和浮点型的赋值规则不一样啊。呵呵

晚上不上线的,刚上来, 不好意思哈, 你这个问题其实涉及到jvm。 jvm是基于栈的机器,几乎所有的指令都与操作数栈相关。栈操作包括把常量压入操作数栈、执行通用的栈操作、在操作数栈和局部变量之间往返传输值。常量值隐含包含在操作码内部。
比如我敲下如下代码编译一下:
int a  = 56;
short s = 57;//为了区别于a,这边用57
s = (short)(s+1);//你这里可以试试,不加short会怎样?
s+=1;//这里为什么可以,在反汇编生成的字节码里面就看出来了
double d = 3.14;
float f = 3.15f;//如果不加f 为什么会不过,在字节码里面也可以看到
编译一下, 然后用反汇编器看看java编译器为我们生成的字节码。这样就可以对照源代码和字节码,从而了解很多编译器内部的工作。 反汇编后如图
一个简单而有趣的类型转换有关问题

看见没有, 是bipush,实际上一开始认为常量56也好或者57也好, 都是当做byte 隐式转换上来的 没有超过short的范围,当然可以通过。
那么接下来, 我们如果加一句,看看结果又会变成什么样子?

一个简单而有趣的类型转换有关问题
这里9999为什么用sipush?

说明在赋值常量的时候是从低到高的。你甚至可以认为,在jvm里面,常量池的数据类型跟每个数据类型取值范围的定义是一样的,有兴趣的话, 你可以试试看int a =2147483647,看看生成的字节码是什么?

热点排行