마지막으로 자바에서 실행되지 않을 수있는 조건이 있습니까? 감사.
~로부터썬 튜토리얼
참고 : try가 실행되는 동안 JVM이 종료되면 또는 catch 코드가 실행되고 있으면 finally 블록은 실행되지 않을 수 있습니다. 마찬가지로, 스레드를 실행하는 스레드가 코드를 시도하거나 catch하는 것이 중단되거나 살해 당했다. 응용 프로그램을 전체가 계속됩니다.
마침내 블록이 실행되지 않는 다른 방법에 대해서는 모른다.
System.exit가상 시스템을 종료합니다.
현재 실행중인 Java를 종료합니다. 가상 기기. 인수가 제공됩니다. 상태 코드로; 관례 상, 0이 아닌 상태 코드가 비정상임을 나타냅니다. 종료.
이 메소드는
exit
방법 수업Runtime
. 이 방법은 결코 정상적으로 돌아옵니다.
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
"bye"는 위 코드에서 인쇄하지 않습니다.
다른 사람들이 말한 것을 확장하기 만하면 JVM이 종료되는 것과 같은 일을 일으키지 않는 것이 finally 블록을 초래할 것입니다. 그래서 다음과 같은 방법 :
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
이상하게도 컴파일하고 반환합니다.
System.exit과 관련하여 finally 블록이 실행되지 않을 수도있는 치명적인 오류 유형도 있습니다. JVM의 메모리가 완전히 소모되면 catch 나 finally없이 종료 될 수 있습니다.
특히, 나는 우리가 어리석게도 사용하려고했던 프로젝트를 기억한다.
catch (OutOfMemoryError oome) {
// do stuff
}
JVM에 catch 블록을 실행하기위한 메모리가 남아 있지 않기 때문에 작동하지 않습니다.
try { for (;;); } finally { System.err.println("?"); }
이 경우 마침내 실행되지 않습니다 (단,Thread.stop
도구 인터페이스를 통해 등가라고합니다).
throw
, 그 다음에finally
블록이 예상대로 실행됩니다.try { throw new ThreadDeath(); } finally { System.err.println("?"); }
- Tom Hawtin - tackline
Sun의 튜토리얼은,이 thread로 잘못 인용되고 있습니다.
참고 : try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록의지실행되지 않습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 인터럽트되거나 죽는 경우 finally 블록의지응용 프로그램 전체가 계속 실행 되더라도 실행되지 않습니다.
마침내 차단을 위해 태양 튜토리얼을 들여다 보면 "실행되지 않을 것"이라고 말하지는 않지만 "실행하지 않을 수 있습니다" 다음은 올바른 설명입니다.
참고 : try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록할 수있다실행되지 않습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 인터럽트되거나 죽는 경우 finally 블록할 수있다응용 프로그램 전체가 계속 실행 되더라도 실행되지 않습니다.
이 동작의 명백한 이유는 system.exit ()에 대한 호출이 런타임 시스템 스레드에서 처리되기 때문에 jvm을 종료하는 데 시간이 걸릴 수 있습니다. 스레드 스케줄러는 마침내 실행을 요청할 수 있습니다. 마지막으로 항상 실행되도록 설계되었지만 jvm을 종료하는 경우 jvm이 마침내 실행되기 전에 종료 될 수 있습니다.
또한 교착 상태 / 라이브 록이 내부에서 발생하는 경우try
블록.
다음은이를 보여주는 코드입니다.
public class DeadLocker {
private static class SampleRunnable implements Runnable {
private String threadId;
private Object lock1;
private Object lock2;
public SampleRunnable(String threadId, Object lock1, Object lock2) {
super();
this.threadId = threadId;
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
synchronized (lock1) {
System.out.println(threadId + " inside lock1");
Thread.sleep(1000);
synchronized (lock2) {
System.out.println(threadId + " inside lock2");
}
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
public static void main(String[] args) throws Exception {
Object ob1 = new Object();
Object ob2 = new Object();
Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
t1.start();
t2.start();
}
}
이 코드는 다음과 같은 출력을 생성합니다.
t1 inside lock1
t2 inside lock1
"마침내"인쇄되지 않음
다음은 finally 블록을 우회 할 수있는 몇 가지 조건입니다.
마지막 비 데몬 스레드 종료 예 :
public class TestDaemon {
private static Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
산출:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
play 프레임 워크와 관련하여 구체적으로 실행하지 않는 finally 블록의 매우 구체적인 경우를 보았습니다.
나는이 컨트롤러 액션 코드의 finally 블록이 Exception 후에 만 호출되었지만 호출이 실제로 성공했을 때 결코 호출되지 않았다는 것에 놀랐다.
try {
InputStream is = getInputStreamMethod();
renderBinary(is, "out.zip");
catch (Exception e) {
e.printStackTrace();
} finally {
cleanUp();
}
renderBinary ()가 호출 될 때 스레드가 종료되었거나 무언가가되었습니다. 나는 다른 render () 호출에 대해서도 같은 일이 일어날 것이라고 생각하지만, 그것을 검증하지는 않았다.
try / catch 후에 renderBinary ()를 이동하여 문제를 해결했습니다. 추가 조사를 통해 play는 컨트롤러 액션이 실행 된 후에 실행되는 메서드를 만들기위한 @Finally 주석을 제공한다는 것을 알 수있었습니다. 여기서주의해야 할 점은 컨트롤러에서 ANY 액션을 실행 한 후에 호출된다는 것이므로 항상 좋은 선택이 아닐 수 있습니다.
다음과 같은 경우에는 finally 블록이 실행되지 않습니다.
System.exit(0)
~에서 호출 됨try
블록.try
블록마침내 블록이 실행되지 않는 다른 프린지 케이스도있을 수 있습니다.
finally 블록 코드 실행을 중지하는 방법에는 두 가지가 있습니다.
1. System.exit ();을 사용하십시오.
2. 어떻게 든 실행 제어가 블록에 도달하지 못하면.
만나다:
public class Main
{
public static void main (String[]args)
{
if(true){
System.out.println("will exceute");
}else{
try{
System.out.println("result = "+5/0);
}catch(ArithmeticException e){
System.out.println("will not exceute");
}finally{
System.out.println("will not exceute");
}
}
}
}
//If ArithmeticException Occur Inner finally would not be executed
class Temp
{
public static void main(String[] s)
{
try
{
int x = 10/s.length;
System.out.println(x);
try
{
int z[] = new int[s.length];
z[10] = 1000;
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
}
finally
{
System.out.println("Inner finally");
}
}
catch(ArithmeticException e)
{
System.out.println(e);
}
finally
{
System.out.println("Outer Finally");
}
System.out.println("Remaining Code");
}
}