我只是注意到了这个问题,并且想把我的$ .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等)来说,这通常不成问题。