Java编译器不能通过的语句_为什么Java有一个“无法访问的语句”编译器错误?...

我只是注意到了这个问题,并且想把我的$ .02添加到这个。

在Java的情况下,这实际上不是一个选项。 “无法访问的代码”错误并不是来自于JVM开发人员认为要保护开发人员不受任何事情影响的事实,也不是来自JVM规范要求的额外警惕。

Java编译器和JVM都使用所谓的“堆栈映射”,即为当前方法分配的有关堆栈中所有项目的明确信息。 必须知道堆栈中每个插槽的types,以便JVM指令不会将另一种types的项目作为干扰项目。 这对于防止将数值用作指针来说是非常重要的。 使用Java程序集可以尝试推送/存储一个数字,然后popup/载入一个对象引用。 但是,在类validation过程中,JVM将拒绝这个代码,即在创build堆栈映射并testing其一致性时。

为了validation堆栈映射,虚拟机必须遍历方法中存在的所有代码path,并确保无论执行哪条代码path,每条指令的堆栈数据都与之前的代码所推送的内容一致/存储在堆栈中。 所以,在简单的情况下:

Object a; if (something) { a = new Object(); } else { a = new String(); } System.out.println(a);

在第3行,JVM会检查两个分支是否只存储到一个(这只是局部variables#0)的东西是兼容的对象(因为这是如何代码从第3行,将对待本地var#0 )。

当编译器得到一个不可达的代码时,它并不完全知道堆栈可能处于什么状态,所以无法validation它的状态。 由于它不能跟踪局部variables,所以在这一点上不能完全编译代码,所以不会在类文件中留下这种不明确的地方,而是会产生一个致命的错误。

当然,像if (1<2)这样的简单条件会欺骗它,但这并不是真的愚蠢 – 它给了它一个可能导致代码的潜在分支,至less编译器和虚拟机都可以确定堆栈物品可以从那里使用。

PS我不知道.NET在这种情况下做了什么,但是我相信它也会编译失败。 对于任何机器代码编译器(C,C ++,Obj-C等)来说,这通常不成问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值