为什么java允许run()抛出未处理的异常,同时限制已处理的异常?
据说运行不会抛出已处理的异常。JVM只是忽略了它们。所以我抛出了未处理的异常(算术异常)。但同样的事情也发生在它身上。 我知道,尝试从标记为XXX的catch子句启动的线程捕获Exception是很不可思议的。因为执行可能已经越过了那条线。为什么java允许run()抛出未处理的异常,同时限制已处理的异常?,java,multithreading,exception-handling,Java,Multithreading,Exception Handling,据说运行不会抛出已处理的异常。JVM只是忽略了它们。所以我抛出了未处理的异常(算术异常)。但同样的事情也发生在它身上。 我知道,尝试从标记为XXX的catch子句启动的线程捕获Exception是很不可思议的。因为执行可能已经越过了那条线。 但我想知道为什么java允许run抛出未处理的异常,而限制已处理的异常,以及run()抛出未处理的异常时会发生什么 父线程 public class Parent { public static void main(String[] args) {
但我想知道为什么java允许run抛出未处理的异常,而限制已处理的异常,以及run()抛出未处理的异常时会发生什么 父线程
public class Parent {
public static void main(String[] args) {
Child child = new Child();
Thread chThread = new Thread(child);
try {
chThread.start();
} catch (Exception e) { // XXX mark
System.err.println("XXX");
e.printStackTrace();
}
}
public class Child implements Runnable {
@Override
public void run() throws ArithmeticException{
method0(); // line 8
}
public void method0(){
int i = 0/0; // line 12
}
}
public class Thread implements Runnable {
public void run() {
if (target != null) {
target.run(); // line 619
}
}
}
子线程
public class Parent {
public static void main(String[] args) {
Child child = new Child();
Thread chThread = new Thread(child);
try {
chThread.start();
} catch (Exception e) { // XXX mark
System.err.println("XXX");
e.printStackTrace();
}
}
public class Child implements Runnable {
@Override
public void run() throws ArithmeticException{
method0(); // line 8
}
public void method0(){
int i = 0/0; // line 12
}
}
public class Thread implements Runnable {
public void run() {
if (target != null) {
target.run(); // line 619
}
}
}
java.lang.Thread
public class Parent {
public static void main(String[] args) {
Child child = new Child();
Thread chThread = new Thread(child);
try {
chThread.start();
} catch (Exception e) { // XXX mark
System.err.println("XXX");
e.printStackTrace();
}
}
public class Child implements Runnable {
@Override
public void run() throws ArithmeticException{
method0(); // line 8
}
public void method0(){
int i = 0/0; // line 12
}
}
public class Thread implements Runnable {
public void run() {
if (target != null) {
target.run(); // line 619
}
}
}
StackTrace
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at seperateStacksPerThread.Child.method0(Child.java:12)
at seperateStacksPerThread.Child.run(Child.java:8)
at java.lang.Thread.run(Thread.java:619)
run()
的签名不包括选中的异常。因此,您无法覆盖它以引发选中的异常(当您覆盖时,您的限制性再大不过了)。
但是允许抛出未经检查的异常,因为它不是签名的一部分(不需要任何人来捕获它)。
当您抛出算术异常时,它是另一个线程堆栈跟踪的一部分。
请注意,它说:
线程“thread-0”java.lang.arithmetricexception:/by zero中的异常
和不:线程“main”java.lang.arithmetricexception:/by zero异常
现在为什么不允许检查异常,这是一个设计决策,我认为这是因为没有人能够捕获它们,因为线程是一个单独的执行流。首先,所有方法都可能抛出未检查异常
接下来,run()
不抛出已检查异常的简单原因是没有人可以捕获它们!该方法作为其“main”方法从启动线程中调用,它是顶级入口点。上面没有任何东西可以处理异常,因此声明抛出异常的方法毫无意义。你的意思是说checked/unchecked吗?完全是NPE!checked-Handled,unchecked-unhandled。您认为应该允许线程的run方法抛出checked异常吗?如果可以,谁来处理?检查异常是程序(可以/应该)处理的异常。但是对于未经检查的异常,你不能对此采取任何措施,它们可能发生在程序中的任何地方。不,我认为是相反的。未处理的也必须限制为抛出。如果不是,为什么?在java中,任何方法(带或不带throws子句)都可以抛出未经检查的异常。这是因为未检查的异常很少是可预测的(这就是为什么它们未检查的原因)。当然,如果(i==0)抛出ArithmaticErrorException(),您可以编写;但是一个更好的代码会将这个问题包装在一个检查过的异常(可能是IisZeroException)中并处理它(try catch),因为您知道当i为零时该怎么做。如果你根本不期望零,那么就不需要检查。那么为什么允许抛出未处理的异常呢?@NamalFernando。。因为未检查的异常
未被编译器检查。您可以向重写方法的throws子句添加额外的未检查异常,但编译器会忽略这些异常。@NamalFernando:因为您可以理解,在执行流程中,您可能会得到异常。某些异常可以在该线程内捕获和处理,例如,无法连接到服务器,但可以在几秒钟内重试,但某些异常根本无法处理,例如,重试5次后,无法连接到服务器,并且您无法执行任何操作,因此您可以抛出未检查的异常以指示错误,该线程将终止。那里没有人可以捕获它们我不太同意这一点。例如,如果您使用一个执行器,它将在一个try/catch(Throwable)
中执行每个run
。因此,这与其说是没有人捕捉它,不如说是一种不同的执行流,使得无法在OP中的代码中捕捉它。