Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java编译器拒绝将System.exit()识别为过程终止?_Java_Compiler Errors - Fatal编程技术网

为什么Java编译器拒绝将System.exit()识别为过程终止?

为什么Java编译器拒绝将System.exit()识别为过程终止?,java,compiler-errors,Java,Compiler Errors,Java的编译器,至少是我使用的Oracle编译器,拒绝将System.exit()识别为过程终止。例如,以下代码给出了一个编译错误: public static int readInteger( ArrayList<String> listLines, int iLineNumber0 ){ try { int value = Integer.parseInt( listLines.get( 0 ) ); return value;

Java的编译器,至少是我使用的Oracle编译器,拒绝将System.exit()识别为过程终止。例如,以下代码给出了一个编译错误:

public static int readInteger( ArrayList<String> listLines, int iLineNumber0 ){
    try {
        int value = Integer.parseInt( listLines.get( 0 ) );
        return value;
    } catch( Throwable t ) {
        System.err.println( "error reading line: " + iLineNumber0 + ": " + t );
        System.exit( -1 );
    }
}
publicstatic int readInteger(ArrayList listLines,int-ilineumber0){
试一试{
int value=Integer.parseInt(listLines.get(0));
返回值;
}捕获(可丢弃的t){
System.err.println(“错误读取行:+ilineumber0+”:“+t”);
系统退出(-1);
}
}
错误是:“缺少return语句”。因此,要使这项工作正常,我必须添加一个如下的return语句(编译成功):

publicstatic int readInteger(ArrayList listLines,int-ilineumber0){
试一试{
int value=Integer.parseInt(listLines.get(0));
返回值;
}捕获(可丢弃的t){
System.err.println(“错误读取行:+ilineumber0+”:“+t”);
系统退出(-1);
}
返回0;//无法访问的代码
}
具有讽刺意味的是,所需的最终返回语句是无法访问的代码,尽管编译器也没有意识到这一点

Java的编译器,至少是我使用的Oracle编译器,拒绝将System.exit()识别为过程终止

是的,会的。就编译器而言,它只是一个
void
方法。在方法签名中无法表示“此方法永远不会正常返回”,在语言中也没有这样的概念。例如:

public void alwaysThrow()
{
    throw new RuntimeException();
}

...

alwaysThrow();
System.out.println("This line is never reached");
int foo() {
    int x = someValue();
    if (x > 10) {
       return 1;
    }
    if (x <= 10) {
       return 20;
    }
    // Is this reachable or not?
}
就编译器而言,上面代码段的最后一行仍然可以访问,尽管我们知道它永远不会执行。同样,您的额外返回语句在技术上是可以访问的,但实际上是无法访问的

基本上,这可以被认为是语言中的一个缺陷,尽管据我所知,它影响了大多数语言。虽然能够像这样表示方法会很好,但它在现实生活中很少是一个真正的问题

如果您发现自己被它困扰,您可以编写一个helper方法:

public RuntimeException systemExit(int exitValue)
{
    System.exit(exitValue);
    return new RuntimeException("Shouldn't get here");
}
然后称之为:

throw systemExit();
这将确保编译器无法访问语句结尾,因此您可以:

catch (Throwable t) {
    System.err.println("error reading line: " + iLineNumber0 + ": " + t);
    throw systemExit(-1);
}
。。。你的编译器错误就会消失

注意,在其他类似的情况下,可达性并不是我们想要的一切。例如:

public void alwaysThrow()
{
    throw new RuntimeException();
}

...

alwaysThrow();
System.out.println("This line is never reached");
int foo() {
    int x = someValue();
    if (x > 10) {
       return 1;
    }
    if (x <= 10) {
       return 20;
    }
    // Is this reachable or not?
}
intfoo(){
int x=someValue();
如果(x>10){
返回1;
}

如果(x错误不是因为
System.exit()
code,但方法期望catch中有返回值,但
syetm.exit
返回类型无效

完整的场景解释

任何方法如果期望
return
value,那么该方法在所有可能的情况下都应该返回一个值,并且在所有情况下也只能返回一个
return

但在你的第一个案例中

您已将
return
仅放在try上,而不放在catch上,因此它将作为预期的return语句进行抱怨。因为在异常发生时并没有返回,并且在catch块下捕获了异常

在你的第二个案例中

您已将
return
放在try和try/catch之外。然后return成为不可访问的代码,因为try已经有了return,所以它不应该有多个return,因为在try之后还有一个return,这在java中是非法的

所以解决方案

将return放在try-and-catch中,但不要放在try/catch之外

把回程直接放在外边,试着接住

解决方案1计划

public static int readInteger( ArrayList<String> listLines, int iLineNumber0 ){
 int value = 0;
    try {
        value = Integer.parseInt( listLines.get( 0 ) );
        return value;
    } catch( Throwable t ) {
        System.err.println( "error reading line: " + iLineNumber0 + ": " + t );
        System.exit( -1 );
     return value;
    }
}
publicstatic int readInteger(ArrayList listLines,int-ilineumber0){
int值=0;
试一试{
value=Integer.parseInt(listLines.get(0));
返回值;
}捕获(可丢弃的t){
System.err.println(“错误读取行:+ilineumber0+”:“+t”);
系统退出(-1);
返回值;
}
}
解决方案2计划

public static int readInteger( ArrayList<String> listLines, int iLineNumber0 ){
 int value = 0;
    try {
        value = Integer.parseInt( listLines.get( 0 ) );
        //return value;
    } catch( Throwable t ) {
        System.err.println( "error reading line: " + iLineNumber0 + ": " + t );
        System.exit( -1 );
    // return value;
    }
return value;
}
publicstatic int readInteger(ArrayList listLines,int-ilineumber0){
int值=0;
试一试{
value=Integer.parseInt(listLines.get(0));
//返回值;
}捕获(可丢弃的t){
System.err.println(“错误读取行:+ilineumber0+”:“+t”);
系统退出(-1);
//返回值;
}
返回值;
}

如果有任何疑问,请告诉我。

您可以在try-catch块之外返回您的值:

public static int readInteger( ArrayList<String> listLines, int iLineNumber0 ){
    int value = 0;

    try {
        value = Integer.parseInt( listLines.get( 0 ) );
    } catch( Throwable t ) {
        System.err.println( "error reading line: " + iLineNumber0 + ": " + t );
        System.exit( -1 );
    }

    return value;
}
publicstatic int readInteger(ArrayList listLines,int-ilineumber0){
int值=0;
试一试{
value=Integer.parseInt(listLines.get(0));
}捕获(可丢弃的t){
System.err.println(“错误读取行:+ilineumber0+”:“+t”);
系统退出(-1);
}
返回值;
}

考虑一下:您加载了另一个运行时库,它的
系统.exit
没有退出。现在在方法结束时会发生什么?编译器希望对此有一个具体的答案,因此它不会对
系统.exit
(或
运行时.exit
)做出任何特殊的假设

如果它这样做了,这只会给语言规范增加复杂性,而没有真正的好处。退出调用并不常见,事实上,您的代码不是使用退出调用的好例子,因为即使它不需要unached return语句,它仍然隐藏了导致问题的原始异常。我将替换println/Exit calls与:

throw new RuntimeException("Error reading line " + iLineNumber0, t);
在非void方法中确实需要退出调用时,可以很容易地在其下方添加
throw null;
throw new Error();
return…;

具有讽刺意味的是,所需的最终返回语句是无法访问的代码,尽管编译器也没有意识到这一点


无法添加此功能,因为它会破坏现有代码。

因为它不是--它只是一个方法调用,与任何其他调用都无法区分。您还可以
返回val