我原以为这个程序会给我带来编译错误,但它成功地编译了,我在运行它时得到了一个运行时异常。
class substr11
{
public static void main(String args[])
{
String s = "abcde";
System.out.println(s.substring(1,-1));
}
}编译器错误应该能够解析(字符串在主体本身中初始化),并发现此字符串操作将导致编译错误,对吗?有人能告诉我为什么它没有抛出编译错误吗?
线程"main“java.lang.StringIndexOutOfBoundsException中的异常: String超出范围:-2在java.lang.String.substring(未知源)的子字符串11.main(substrat11.java:9)处
发布于 2013-08-22 07:40:55
编译错误是编译器无法编译代码(语法错误、缺少符号等)时的错误。
在您的程序中不是这样的,您按照预期将两个int传递给String#substring,并且您没有遗漏任何东西(没有缺少的类,括号是OK的,分号是应该的),那么编译器为什么要关心呢?
如果代码编译了,但由于某些异常(如ArrayIndexOutOfBounds)而崩溃,则会出现异常。
发布于 2013-08-22 07:40:45
编译器从不将其解析或优化为方法调用。尽管子字符串操作可能无效并具有硬连接参数,但这并不重要,因为它不会解析整个方法调用。
该调用可能会产生副作用,或者只在复杂的条件集(包括实例、静态变量,甚至库的选择)下抛出运行时异常。
编译错误可能包括无效语法,但不包括以下内容。方法调用是有效的。也许某个字符串可以为它的子字符串方法接受这组参数。编译器不会对该字符串执行复杂的分析。
如果这样做的话,编译将花费很长时间,并且会出现许多,许多错误。
发布于 2013-08-22 07:41:36
代码中没有编译时错误。对substring()的调用采用两个int's,这是对方法的有效调用。
编译器不检查字符串内容,因此它没有看到这将在运行时抛出异常。
就编译器所见,s变量仅被假定为String,对其内容没有任何假设。在这种情况下,它被分配了一个常量值,但是它可能是一些无法实现的东西,比如数据库查询结果,或者其他任何东西。这同样适用于函数的int参数。
总之,正如他在回答中指出的那样,编译器不会对输入进行复杂的分析。开发人员负责对输入进行必要的检查,以避免运行时或检查异常,或相应地捕获它们。
https://stackoverflow.com/questions/18374373
复制相似问题