解决方案 »

  1.   

    3.14默认是double类型,你把double类型数据复制给float当然不行,float f = 3.14f;这样就行了。
    给short赋值,只要在-32768到32767之间就没问题
      

  2.   

    整数就没什么精度了吧,
    不过short s = 100000;好像不可以
      

  3.   

    short s = 56;没有问题啊,56在short能表示的范围之内。
      

  4.   


    谢谢你的回答,但没说到本质啊。
    我也知道将double类型的数值赋给float类型的变量当然不行,但将int类型的数值赋给short类型的变量就可以?
    大范围的类型值赋给小范围的类型变量时不是要强制类型转换么?
      

  5.   


    那 3.14也在float表示的范围内啊~ 呵呵
      

  6.   


    那 3.14也在float表示的范围内啊~ 呵呵
    3.1333333333333333   <   3.14能用float表示么?小数一般说的也是精度。
      

  7.   

    int a = 56; //数值56默认为int类型  
    我怎么不知道??
      

  8.   


    Java语言的整型常量本来就默认是int型的,Java浮点型常量默认是double类型。int a = 2147483647;//编译通过
    int a = 2147483648;//编译不通过这难道还说明不了问题么。
      

  9.   

    是我没把问题描述清楚么?其实总结一下就是:
    short s = 56; //为什么能通过编译?int类型的数值56 为什么能直接赋给 short类型的变量s 而不需要强制类型转换?作为对比,float f = 3.14; 都通不过编译 , 必须写成  float f = (float)3.14; 才行。
      

  10.   

    Java语言是一种强类型的语言。强类型的语言有以下几个要求:
    变量或常量必须有类型
    要求声明变量或常量时必须声明类型,而且只能在声明以后才能使用。
    赋值时类型必须一致
    值的类型必须和变量或常量的类型完全一致。
    运算时类型必须一致
    参与运算的数据类型必须一致才能运算。在整数之间进行类型转换时,数值不发生改变, jvm会自己做个隐式转换的
    Java常用的数据类型,都是有固定顺序的,低类型向高类型转,可以认为是隐式;高类型要转成低类型,必须要显示的转换。你在int a = 56; //数值56默认为int类型 ?? 你这是定义a是int类型
    short s = 56; //你这是定义s是short类型 56是个常量 从汇编角度讲,常量是在指令上的量,就像指令中的立即数寻址,系统取到指令后不需要通过地址再去取数据,它不占空间,也就没有地址的概念,当然有人认为系统对常量和变量都有空间存储,只是对待不同。
    而变量是在内存中有个空间对它进行存储,指令保存它的地址。我们可以认为,常量在编译后所占用的内存大小已经确定,所以常量1在内存里就是二进制1,而变量需要在运行时进行分配,因此要根据变量的数据类型进行空间开辟,也就是先根据数据类型来n个0,然后把1塞进去需要注意的一点就是int a = 56;这一句,a是a,56是56,虽然值一样。
    只看a和56,它们两个都是存放在栈内存中。
    我们知道存放在栈中的数据大小与生存期必须是确定的,所以a根据它的数据类型int占用4字节,看到的二进制就是00000000 00000000 00000000 00000000。
    再看56,他是个地道的常量,他所占用的栈内存空间就是由它本身确定也就是111000。
    然后将56赋值给a,就是将a指向到56,但不管a也好还是56也好,他们本身的内存空间大小都没有发生改变,所以我们看到a的二进制就是00000000 00000000 00000000 00111000,而56则是111000综上,我们看到的a和56的内存空间是两块不同的内存空间。你用short s = 56 也是一样的这个步骤,那么既然56 这个常量没有超出short的范围,那么这么定义编译通过有什么不可以?你要是要是改成这样:
    int a = 56;
    short s = a;
    你可以自己试试看能编译过不?如果不行 你再改成
    int a = 56
    short s = (short) a;
    这次看看可以了不?
      

  11.   

    至于你说的3.14 那是因为
    float和double是表示浮点型的数据类型,他们之间的区别在于他们的精确度不同float 3.402823e+38 ~ 1.401298e-45(e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方)占用4个字节double 1.797693e+308~ 4.9000000e-324 占用8个字节double型比float型存储范围更大,精度更高,所以通常的浮点型的数据在不声明的情况下都是double型的。也就是说,在不声明的情况下,他默认浮点数是double类型,你想把一个double类型赋值给float类型,而且是从高类型转低类型,违反了从高转低需要显式转换的规则,当然编译不过。
      

  12.   


    好,你说数值3.14默认是double类型对吧,那数值56是什么类型?
      

  13.   


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

  14.   

    http://justjavac.iteye.com/blog/1073775
      

  15.   


    谢谢你打了这么多字但我还是有些疑问,你说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,看看生成的字节码是什么?
      

  16.   


    谢谢你打了这么多字但我还是有些疑问,你说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,看看生成的字节码是什么?
    short s = 57;//为了区别于a,这边用57
    s = (short)(s+1);//你这里可以试试,不加short会怎样?

    对啊,为什么+1,编译器又认为1是int类型了?等于是将short的57隐式的转换成了int型然后加int的1?这是为什么?