2016-06-17 62 views
16

我有一個問題System.exit(0);。 當我嘗試下面的代碼輸出是什麼,因爲System.exit(0);System.exit(0)不會阻止最終被調用時SecurityManager.checkExit拋出異常

String number = "12345M"; 
try { 
    System.exit(0); 
} catch (Exception e) { 
    System.out.println("Exception caught"); 
} finally { 
    System.out.println("inside finally"); 
} 

但是,當我嘗試這樣做下面的代碼:

System.setSecurityManager(new SecurityManager() { 
    @Override 
    public void checkExit(int status) { 
     throw new ThreadDeath(); 
    } 
}); 

try { 
    System.exit(0); 
} finally { 
    System.out.println("I am finally block"); 
} 

是輸出:

我終於塊

有人可以請解釋這種不同的行爲?

+2

不能阻止最終被調用。 –

回答

18

因爲exitThreadDeath例外防止(這不是一個你應該BTW投擲自己):

SecurityException - 如果安全管理器存在並且其checkExit方法不允許以指定的退出狀態。

https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#exit(int)

請注意,您應該拋出一個SecurityException,以防止出口如:

System.setSecurityManager(new SecurityManager() { 
    @Override 
    public void checkExit(int status) { 
     throw new SecurityException("Not allowed."); 
    } 
}); 

try { 
    System.exit(0); 
} catch(SecurityException e) { 
    System.out.println("Exit failed."); 
} finally { 
    System.out.println("I am finally block"); 
} 
System.out.println("Program still running"); 

輸出:

Exit failed. 
I am finally block 
Program still running 
3

Quoting

java.lang.SecurityManager類允許應用程序實現安全策略。它允許應用程序在執行可能不安全或敏感的操作之前確定操作是什麼以及是否在允許執行操作的安全上下文中嘗試該操作。該應用程序可以允許或禁止該操作。

在上面的代碼中,checkExit決定操作是否被允許操作,並且通常會工作並因此退出。由於引發異常,操作因此被確定爲不安全並且被阻止執行。

請參閱http://www.tutorialspoint.com/java/lang/system_exit.htm

4

當你調用System.exit()無需重寫checkExit()方法時,JVM在這一點上停止終於不叫。

但是,當您重寫checkExit()方法時,會引發異常並最終被調用。

2

System.exit(0);是調用,它會調用Runtime.exit隨後在它中,它將檢查是否連接了SecurityManager。 如果連接了一個,它將執行checkExit方法。

看到代碼在Runtime.exit

public void exit(int status) { 
    SecurityManager security = System.getSecurityManager(); 
    if (security != null) { 
     security.checkExit(status); 
    } 
    Shutdown.exit(status); 
} 

因此,在你的代碼的系統實際上沒有,當你調用System.exit(0);退出,因爲你扔在SecurityManager.checkExit

Shutdown.exit(status);一個例外,不會被調用的VM不會停止,它將繼續執行任何語句,然後它將到達main方法的結尾並終止。

更改你像這樣的代碼和玩

如果System.exit()的是從防止做到這一點是你應該期望它不工作
System.setSecurityManager(new SecurityManager() { 
           @Override 
           public void checkExit(int status) { 

            if(status == 0){ 
             System.out.println("Not going to finally"); 
            }else{ 
             throw new SecurityException(); 
            } 

           } 
          }); 

    try { 
     System.exit(1); 

    } catch (Exception e){ 
     e.printStackTrace(); 
    }finally { 
     System.out.println("I am finally block"); 
    } 

    System.out.println("System.exit(1) Didn't work ......"); 

} 

看看System.exit的Java doc和Runtime.exit DOC