它是在Java中设计的,如果在Throwable上调用getCause(),则会得到一个Exception对象。我知道getCause()只是从Throwable继承而来的,而且我知道Throwable可以是Error或Exception,但是程序员通常只应在Exception级别上工作而不处理 / Throwable类。例如,在Java异常层次结构设计中,为什么不将Error包含在会返回getCause()对象的Exception类中的原因是什么?这是从Java Concurrency in Practice(Brian Goetz)中摘录的不便之处:public class Preloader { private final FutureTask<ProductInfo> future = new FutureTask<ProductInfo>(new Callable<ProductInfo>() { public ProductInfo call() throws DataLoadException { return loadProductInfo(); } }); private final Thread thread = new Thread(future); public void start() { thread.start(); } public ProductInfo get() throws DataLoadException, InterruptedException { try { return future.get(); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof DataLoadException) throw (DataLoadException) cause; else throw launderThrowable(cause); } }}书中说: ...而且还因为Exception的原因是作为ExecutionException返回的,这不方便处理...在Throwable中,它被处理为立即重新抛出launderThrowable()(因为我们不想处理它)并返回Error:public static RuntimeException launderThrowable(Throwable t) { if (t instanceof RuntimeException) return (RuntimeException) t; else if (t instanceof Error) throw (Error) t; else throw new IllegalStateException("Not unchecked", t);} 最佳答案 首先,如果您的类型具有几个子类型,并且它们的行为确实相同,那么在父类中定义方法是有意义的。基本上,设计师说的是:“ Throwable可能有原因,这也是可抛出的,您可以得到该原因”。您可以在Exception和Error中都这样做,因为它们都碰巧是可抛出的。现在,Throwable层次结构从Java 1.0开始就存在,并且泛型在那里不存在。如今,您可能已经可以定义如下行为:class ModernThrowable<T extends ModernThrowable<T>> { T getCause() {...}}然后可以将ModernException定义为extends ModernThrowable<ModernException>,然后可以得到您期望的行为。但是这种设计当时还不存在,所以您又得到了Throwable,并且必须对其进行强制转换。这就是过去的工作方式,您必须保持向后兼容性。但是实际上……听起来可能如此,这是不正确的。至少,这不是全部。使Error成为Exception的原因是完全可以的。看看javax.management.RuntimeErrorException。与代理一起工作时,您可能会得到Error,在这些特殊情况下,该getCause()不应导致您立即中止系统。因此,您将其作为此特殊Exception的原因。因此,您的Error实际上将从Exception返回。因此,如果它不是这样设计的,那么您将不得不经历麻烦–专门针对这种特殊异常的原因使用一种特殊方法。关于java - 如果在异常上调用getCause(),为什么我必须处理Throwable,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31838296/
10-11 03:02