Java 编译器检查整数类型的变量的初始化(声明并初始赋值)的原则是啥??报错-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

Java 编译器检查整数类型的变量的初始化(声明并初始赋值)的原则是啥??报错

2020-06-07 18:11:33 223 1

有人说,Java编译器编译时候,一般都要对 声明并初始化赋值的整数类型(byte, short, int, 和 long) 的变量初始化,进行检查,看看赋值大小是否超过变量的类型所容纳的范围。 如果超过范围, 报错:“从int转换到byte可能会有损失”, 或 “过大的整数: 2147483648”,从而停止编译。 如果要赋予的数值在允许范围之内,则编译通过此行代码。

如下代码 6个变量初始化赋值,全部超过了类型所容纳的范围。从编译信息可见,仅2处编译报错,未通过。

似乎找不出原则,

  1. 对十进制表示的 超值变量 short  s 和 byte b, 有时也不做检查(漏查)。
  2. 声明并初始化相应的包装类对象的时候,对参数 也是 有时检查,有时不检查 。
    public class A{	
    short s = 32800; //Shrt.MAX_VALUE: 32767 未报错
    byte b = 1208;  //Byte.MAX_VALUE:127 未报错
    int i = 2147483648; //Integer.MAX_VALUE 2147483647 报错
    int j = 0x80000000; //2147483648的16进制表示,未报错
    Integer  ii = new Integer(2147483648);//报错
    Integer  ji = new Integer("2147483648");//未报错
    }

    编译输出:

    D:\java\test\OS_China>javac A.java
    A.java:4: 错误: 过大的整数: 2147483648
    int i = 2147483648; //Integer.MAX_VALUE 2147483647 报错
            ^
    A.java:6: 错误: 过大的整数: 2147483648
    Integer  ii = new Integer(2147483648);//报错
                              ^
    2 个错误

     

取消 提交回答
全部回答(1)
  • 爱吃鱼的程序员
    2020-06-08 11:16:51
                        <p><img alt="" height="442" src="https://static.oschina.net/uploads/space/2018/0209/160653_MlXo_437238.jpg" width="677"></p> 
    

    将第4,6行注释掉之后,第2,3行编译报错。4,6行的错误信息是过大的整数,2,3行报错信息为不兼容的类型,可以看出java编译器认为这是两种不同的错误,对其检查的先后不同。

    int j = 0x80000000;

    这个数值表示的是-2147483648,并不超过整数范围,可以使用以下代码查看:

    Integer.toHexString(-2147483648);
    Integer  ji = new Integer("2147483648");

    最后这种情况更不会在编译时候检查,只能在运行时发现报错。

                                回复 <a class="referer" target="_blank">@tcxu</a>  : 1、关于16进制的问题可以去直接查看源码java.lang.Integer,其中:public static final int   MIN_VALUE = 0x80000000;
    

    2、我是将第4和第6行注释掉之后,第2和第3行才报错误的。两种错误的优先级不同。

                            2147483648 的16进制表示是: 0x80000000, 这个数值 高于 int 的上限/范围(整型 int 最大值 Integer.MAX_VALUE:2147483647)1。 因此应当报错。我将注释全部除掉,编译起来, 仍然只有两条错误信息。
                        
    
                            我的环境是:java version "1.8.0_162"
    

    Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode).

                        <p>大原则:当一个编译阶段遇到错误后,就不会继续进行下一个阶段。</p>
    

    首先,字面常量值的处理,所以2147483648超出整形范围以后就会报错。

    然后,变量初始化的处理,所以隐式类型转换时就会报错。

    =========

    针对你的问题:

    1.不是漏检,而是之前的检查出错,就不进行下去了

    2.字符串的类型转换错误,只有运行时才能发现,编译阶段是无法得知的

                                回复 <a class="referer" target="_blank">@Shazi199</a>  : 谢谢你的提醒。
    

    问题是:int 型变量,不可能正确储存数值超过 Integer.MAX_VALUE 的正整数。如果不是动态情况(即,变量声明并初始赋值的情况),java 编译器是否都能检查出来?

                                回复 <a class="referer" target="_blank">@tcxu</a>  : 看来你不懂什么是补码,建议你好好学习一下再回过头来看这个问题
                        
    
                                回复 <a class="referer" target="_blank">@Shazi199</a>  : 输入的是出界的正整数(最大正整数 加 1),结果变成了  -2147483648  。虽然这个负值是最大负值,没出界。但是仍然是垃圾。比如:调用 System.out.println(Integer.MAX_VALUE +1); 输出也一样: -2147483648。难道这个输出不是垃圾吗?
                        
    
                                回复 <a class="referer" target="_blank">@tcxu</a>  : 没有出界啊,这个就是最大负值的表示形式
                        
    
                            好像还不全是这样。有时根本就不检查(或检查不出来)。 如,public class B{	
    

    static int j = 0x80000000; public static void main(String args[]){ System.out.println(j); } } 编译通过,输出的是 -2147483648 (垃圾), 因为初始值出界,变为最大负值。

    0 0
相关问答

40

回答

[@徐雷frank][¥20]什么是JAVA的平台无关性

大河人家 2018-10-29 23:55:20 144699浏览量 回答数 40

162

回答

惊喜翻倍:免费ECS+免费环境配置~!(ECS免费体验6个月活动3月31日结束)

豆妹 2014-10-29 17:52:21 226093浏览量 回答数 162

8

回答

OceanBase 使用动画(持续更新)

mq4096 2019-02-20 17:16:36 336976浏览量 回答数 8

13

回答

[@饭娱咖啡][¥20]我想知道 Java 关于引用那一块的知识

心意乱 2018-10-31 18:44:12 142448浏览量 回答数 13

110

回答

OSS存储服务-客户端工具

newegg11 2012-05-17 15:37:18 295477浏览量 回答数 110

22

回答

爬虫数据管理【问答合集】

我是管理员 2018-08-10 16:37:41 147214浏览量 回答数 22

18

回答

阿里云开放端口权限

xcxx 2016-07-20 15:03:33 646734浏览量 回答数 18

31

回答

[@倚贤][¥20]刚学完html/css/js的新手学习servlet、jsp需要注意哪些问题?

弗洛伊德6 2018-10-27 21:52:43 146027浏览量 回答数 31

42

回答

【精品问答集锦】Python热门问题

小六码奴 2019-05-30 15:27:34 136897浏览量 回答数 42

10

回答

[@墨玖tao][¥20]为什么流式处理框架都是 java 写成的,JVM 是不是在流和批存在着特殊优势。还有分布式资源调度,感觉Mesos 的成长速度跟不上 Yarn。这是为什么?

管理贝贝 2018-10-23 13:18:03 136457浏览量 回答数 10
+关注
爱吃鱼的程序员
https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
2
文章
21569
问答
问答排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载