![]() |
1
64
因为无法访问的代码对编译器来说毫无意义。尽管让代码对人有意义比让它对编译器有意义更重要、更困难,但编译器是代码的主要消费者。Java的设计者认为对编译器没有意义的代码就是一个错误。他们的立场是,如果您有一些无法访问的代码,您就犯了一个需要修复的错误。 Unreachable code: error or warning? ,其中作者说“我个人强烈地感觉到这应该是一个错误:如果程序员写了一段代码,它应该总是有在某些场景中实际运行它的意图。”显然,Java的语言设计者同意这一点。
许多人在评论中指出,有许多类的代码是不可访问的,Java并不阻止编译。如果我正确理解Gdel的结果,那么没有编译器能够捕获所有不可访问代码的类。 单元测试不能捕获每一个bug。我们不会用这个来反驳他们的价值。同样地,编译器不能捕获所有有问题的代码,但是在可能的情况下防止编译坏代码对它来说仍然是有价值的。
(在您否决之前:问题不是Java是否应该有一个不可访问的语句编译器错误。问题是 为什么? Java有一个无法访问的语句编译器错误。不要因为你认为Java做了错误的设计决定就对我投反对票。) |
![]() |
2
47
这看起来很荒谬,任何读过代码的人都会猜到这一定是故意的,而不是一个让其他语句无法访问的粗心错误。 Java对“条件编译”有一点支持 http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.21
|
![]() |
3
19
是保姆。 我觉得.Net做对了这一点-它对无法访问的代码发出警告,但不是错误。有人警告这是好事,但我认为没有理由阻止编译(特别是在调试会话期间,在调试会话中,最好抛出一个返回值来绕过一些代码)。 |
![]() |
4
14
我只是注意到这个问题,想把我的0.02美元加到上面。 对于Java,这实际上不是一个选项。“无法访问的代码”错误并不是因为JVM开发人员认为要保护开发人员免受任何伤害,或者格外警惕,而是因为JVM规范的要求。 Java编译器和JVM都使用所谓的“堆栈映射”(stack maps)——关于堆栈上所有项的明确信息,分配给当前方法。堆栈中每个插槽的类型都必须是已知的,这样JVM指令就不会将一种类型的项误认为另一种类型的项。这对于防止将数值用作指针非常重要。使用Java汇编,可以尝试推送/存储一个数字,但随后弹出/加载一个对象引用。然而,JVM在类验证期间会拒绝这些代码,也就是在创建和测试堆栈映射的一致性时。 为了验证堆栈映射,VM必须遍历一个方法中存在的所有代码路径,并确保无论执行哪个代码路径,每个指令的堆栈数据都与堆栈中任何先前的代码推送/存储的一致。简单来说:
在第3行,JVM将检查“if”的两个分支是否只将与对象兼容的内容存储到一个(这只是本地var#0)中(因为第3行及以后的代码就是这样处理本地var#0的)。 当编译器到达一个不可访问的代码时,它不知道堆栈在那个时候可能处于什么状态,所以它不能验证它的状态。此时它不能再编译代码了,因为它也不能跟踪局部变量,所以它没有在类文件中留下这种模糊性,而是产生了一个致命的错误。
另外,我不知道.NET在这种情况下会做什么,但我相信它也会失败。对于任何机器代码编译器(C、C++、Obj-C等),这通常不会是个问题。 |
![]() |
5
5
编译器的目标之一是排除错误类。有些不可访问的代码是偶然出现的,javac在编译时排除了这类错误是很好的。 对于每个捕获错误代码的规则,有人会希望编译器接受它,因为他们知道自己在做什么。这是编译器检查的代价,而获得正确的平衡是语言设计的关键之一。即使经过最严格的检查,仍然有无限多的程序可以编写,所以事情不会那么糟。 |
![]() |
6
5
虽然我认为这个编译器错误是一件好事,但有一种方法可以解决它。 使用一个你知道是真的条件:
编译器不够聪明,不能抱怨这一点。 |
![]() |
7
0
抱怨编译器越严格越好当然是件好事,因为它允许您做您需要的事情。 |
![]() |
8
0
如果允许的原因
另外两种方法可能很有趣,但不适用于关闭方法代码的一部分
现在,与其说
还有一个问题
除了java是一种“保姆”语言,我更喜欢使用类似C/C++的本地语言来进行更多的控制。 |
|
user29759326 · 如何返回递归函数中的最后一个值? 3 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 4 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 4 月前 |
![]() |
rudraraj · java中未声明最终变量 4 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 4 月前 |