假设此代码:
String[] data = new String[2];
data[0] = "OK";
data[1] = "returning data";
data[2] = "data out of bounds";
肯定会抛出IndexOutOfBounds
例外。
我的问题是:
Eclipse
解析器没有使用warning
或error
抱怨此问题?我发现案件分析:
还有其他类似的警告/错误被检测到:
uninitialized variable
的变量时,List<String> = null
。unreachable code
之后写句子时,return
。unused code
在if
陈述的死分支中。答案 0 :(得分:4)
您可以为Eclipse安装FindBugs插件(可在Eclipse市场上获得)。它能够检测到这样的问题:
答案 1 :(得分:2)
您提到的其他案件并不直接相关:
根据JLS Chapter 16, "Definite Assignment",未初始化的变量是一个普通的编译时错误。
无法访问的代码也是一个编译时错误,根据JLS Section 14.21, "Unreachable Statements"
剩下的最后一个是死代码。这是不错误,原因也在Unreachable Statements部分进行了解释:
有人可能希望以下列方式处理if语句:
...
这种方法与其他控制结构的处理一致。但是,为了使if语句能够方便地用于&#34;条件编译&#34;目的,实际规则不同。
例如,以下语句导致编译时错误:
while (false) { x=3; }
因为声明x = 3;无法到达;但表面上相似的&gt;情况下:
if (false) { x=3; }
不会导致编译时错误。优化编译器可以实现语句x = 3;将永远不会执行,并可能选择从生成的类文件中省略该语句的代码,但语句x = 3;不被视为&#34;无法到达&#34;在这里指定的技术意义上。
所以&#34;死代码&#34;是&#34;不寻常&#34;当然有些东西值得指出,但不一定是错误。
关于你的实际问题(忽略了Parser和Compiler是两个不同的事实 - 它清楚问题是什么):这是一个非常具体的案例。它仅适用于数组的声明和对数组的访问属于同一范围的情况。另外,索引必须是编译时常量。
很明显,
是不可能的void init(String data[]) {
data[0] = "OK";
data[1] = "returning data";
data[2] = "data out of bounds";
}
或
int i = 0;
data[i++] = "OK";
data[i++] = "returning data";
data[i++] = "data out of bounds";
可能没有令人信服的深刻理由说明为什么Eclipse没有检测到这一点,只是检测到这些错误的努力与效益之间的比例不够高 - 所以可能会在未来添加类似这样的东西发布。 Eclipse中已经存在一些相当复杂的警告(例如,自动检测&#34;空指针访问&#34;)。但是对于更详细的静态分析,有一些专用工具,比如FindBugs或PMD,这些工具比随便进行的测试需要更多的努力(顺便说一下,还有更多的时间)飞过日食。
附注:您可以考虑使用
避免此类错误String data[] = {
"OK",
"returning data",
"data out of bounds"
};
答案 2 :(得分:1)
根据Java语言规范,Eclipse没有给出错误消息,因为这是有效的Java代码。如果Eclipse将其视为编译错误,那么它将不是一个合适的Java编译器。有一些原因是因为Eclipse解析器不会因警告或错误而抱怨此问题吗?
警告案例不太明确。是的,Eclipse可以(合法地)提供警告,就像它警告某些涉及NPE的案件一样。但是,在生成有用的警告和编译器检查产生它们的条件的时间之间存在权衡。太多的检查会使编译器对所有程序都变慢,程序员会抱怨那个。 (特别是那些使用数千个类的应用程序的程序员。)
正如@Tagir指出的那样,如果你想收到关于此类事情的警告,请考虑使用FindBugs或PMD等错误检查程序。
还有其他类似的警告/错误被检测到......
您列出的三种情况中的两种都是编译错误,因为Java语言规范声明它们是无效的Java代码。我不确定&#34;死代码&#34;因为不清楚你指的是什么情况。如果你指的是
if (<compile-time-constant-expr>) { ... } else { ... }
然后代码不应该给出编译错误或警告。
答案 3 :(得分:0)
Eclipse解析器不应该检测到这种IndexOutOfBounds 异常?
显然答案是肯定的,因为它很容易被发现。
但是你也可以通过不使用魔法常数来做得更好并避免潜在的错误:
String[] data = new String[] { "OK", "returning data", "data not out of bounds" };