当一个错误不会导致程序崩溃时,这意味着什么
有时候Eclipse会说“你应该调试这条线!!!”但并没有真正关闭程序。然后,我可以继续玩大二,甚至经历了第一次导致错误的相同事件,并获得另一个错误框弹出!当一个错误不会导致程序崩溃时,这意味着什么
错误很简单,我会修复它,我只想知道为什么一些错误是终端,有些不是?有什么不同?
编程错误可以在这些类别进行分类:
- 编译时错误,这是由在编译时编译器捕获并没有纠正他们,这是不可能在所有运行的程序。
- 运行时错误,它不会被编译器捕获,但会使计算机处于无法找出自己要做什么的情况,例如未处理的异常。大多数情况下,这会导致程序在运行时崩溃并崩溃。
- 逻辑错误,这是计算机完全可以接受的,因为它是一个有效的计算机程序,但不会产生您期望的结果。由于电脑不知道你的意图,电脑无法捕捉到他们。
实际上,尽可能让错误尽可能致命是件好事。它使我们更快地找到它们并更轻松地纠正它们。这就是为什么在“安全”的语言(如Java)中,我们检查了异常,而未处理的异常将导致应用程序立即崩溃,而不是继续运行,并可能产生不正确的结果。
我不同意将错误尽可能致命是件好事。完全有可能产生对程序不致命的错误,并且可以(也应该)从错误中恢复。在所有错误条件下做*事*是很重要的,但它不应该总是终端。 – Adrian 2008-12-15 15:50:41
我想你的情况,这是关于异常发生在什么线程(你的应用程序是一个GUI应用程序,对不对?)。如果主线程发生异常,它可能是终端,但是如果它发生在另一个线程中,它不是终端。如果应用程序中的其他线程是守护程序线程,则它是主线程的终端。当线程处于守护进程时,应用程序将在完成之前终止,无论其状态如何。如果它们不是守护进程,应用程序将在终止之前等待它们完成。
我不太了解Eclipse框架,但我想它能够应对GUI线程中的异常。
我已经包括一个示例java应用程序,说明我的例子;
public class ThreadTest {
public static void main(String[] args) {
Runnable test = new Runnable() {
public void run() {
try {
System.out.println("Sleeping");
Thread.sleep(5000);
System.out.println("Slept");
} catch (InterruptedException e) {
}
}
};
Thread t = new Thread(test);
//t.setDaemon(true);
t.start();
System.out.println("Waiting to fail");
throw new RuntimeException("Error");
}
}
您将在取消标记t.setDaemon(true)行时看到行为上的差异。
例如,想象一下您的银行使用的一款软件。
在您的储蓄账户,他们所做的follwoing行:
Account -= Interest;
这显然是一个错误,但它不会导致系统崩溃。
前面的回答中得到这一权利Java的一部分:
如果发生异常在主 线程,它可能是终端,但如果它 在另一个线程时它不是 终端。如果 应用程序中的其他线程是守护进程线程,则它是主线程的主要终端 线程。
更大的事实是,当没有非守护进程线程仍在运行时,应用程序正在运行的JVM将关闭。这或者是显式调用System.exit(或者彻底的JVM崩溃)是JVM完全退出的唯一方式。
在许多更简单的Java应用程序中,只有1个非守护程序线程(JVM在启动时开始运行main()的线程。)因为在简单情况下,运行我们的代码的线程是只有非守护线程,我们得到的印象是未处理的异常导致JVM退出。事实并非如此,除非该线程碰巧是唯一剩下的非守护线程。
您可以用下面的小程序证实这一点:
public class TestMain {
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
while(true) {
System.out.println("A");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("t1 interrupted.");
}
}
}
};
t1.setDaemon(false);
Thread t2 = new Thread() {
public void run() {
int count = 0;
while(true) {
if(count < 5) {
System.out.println("B");
count++;
} else {
throw new RuntimeException("Intentional RuntimeException!");
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("t2 interrupted.");
}
}
}
};
t2.setDaemon(false);
t1.start();
t2.start();
}
}
如果你运行它,你会发现,你得到混合“A” S和“B” S,直到5日“ B”,此时你会得到我们抛出异常的堆栈跟踪,而‘A’的继续(在‘B’S不继续,因为线程刚刚去世,因为未处理的异常。)
现在,如果你回去换t1.setDaemon(false)
到t1.setDaemon(true)
,并再次运行,你会看到,当T2终止,因为异常的,有没有非守护线程剩下的,JVM将退出。
,回答了“为什么一些错误不关闭JVM”的问题。但是它并没有回答关于Eclipse为什么会弹出一个调试器的部分问题。
这个问题的答案是简单的(但我对此有点不太确定的...别人附和):Eclipse调试器暂停任何时候一个线程终止,因为未处理的异常。它假定你并不是说线程死掉了,而且你需要修复这个bug。我相信它实际上是在观察java.lang.ThreadDeath异常,并在任何时候抛出异常。
,如果我们知道什么是错误是这将是有益的。 – 2008-12-15 12:49:23
什么是二大? – 2008-12-15 14:38:55
但是,我的问题是一般?没有具体的错误,我只是好奇为什么一些错误会阻止一个程序,而一些错误不会呢? – Ziggy 2008-12-16 02:23:38