2016-06-10 64 views
0

我已经写了一个方法,它在try语句中返回一些值。在catch中,我调用了handleException,它将具有理解异常并重新抛出新异常的转换逻辑。这里handleException总是抛出异常,getXYZ()仍然给出编译时错误,期望返回语句。我没有处理异常,我只是抛出新的异常,所以为什么该方法想要返回语句。为什么一个方法需要catch语句中的返回语句,即使catch语句重新抛出异常

public String getXYZ(String input) { 
    try { 
     return getFromDAO(input); 
    } catch (Exception e) { 
     handleException(e); 
    } 
} 
private void handleException(Exception e) { 
    try { 
     throw e; 
    } catch(SomeException se) { 
     throw new MyRuntimeException("MyException message", se); 
    } catch(SomeOtherException soe) { 
     throw new MyRuntimeException("MyException message", soe); 
    } 
} 

此方法的其他版本编译。

public String getXYZ(String input) { 
    try { 
     return getFromDAO(input); 
    } catch (Exception e) { 
     throw e; 
    } 
} 
+1

在另一个注释中,您可能想要在方法参数中添加一些throws子句。 [请参阅此处的示例](https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html)稍后将帮助您确保尝试捕获这些“异常”对象 – Draken

回答

4

你是不是在catch块扔东西,你调用你的处理函数,这最终将导致新的异常被抛出,但在getXYZ实际代码catch是做一个函数调用。如果你改变handleException以后在某些情况下不会抛出异常,那么getXYZ会返回什么呢?

+0

什么是使用handleException方法的正确方法?它应该返回异常对象而不是抛出它,然后getXYZ抛出异常? – deepak

+0

为什么不把这些'catch'块放到'getXYZ'中,而不需要''只是将一个异常类型转换为另一个异常类型的'handle'函数? –

+0

我必须在一个类的许多方法中捕捉到相同的异常,所以我正在编写一个单独的私有方法来执行异常转换。 – deepak

1

解决此问题的一种方法是向编译器明确指出您期望抛出异常。

public String getXYZ(String input) { 
    try { 
     return getFromDAO(input); 
    } catch (Exception e) { 
     throw handleException(e); // compiles ok. 
    } 
} 

private RuntimeException handleException(Exception e) { 
    try { 
     throw e; 
    } catch(SomeException se) { 
     return new MyRuntimeException("MyException message", se); 
    } catch(SomeOtherException soe) { 
     return new MyRuntimeException("MyException message", soe); 
    } catch(RuntimeException re) { 
     return re; 
    } catch(Exception e2) { 
     return new MyRuntimeException("MyException message", e2); 
    } 
} 

BTW一种替代的方法是不是在所有包装异常,并留下异常,因为它是。

public String getXYZ(String input) { 
    try { 
     return getFromDAO(input); 
    } catch (Exception e) { 
     throw rethrow(e); // compiles ok. 
    } 
} 

/** 
* Cast a CheckedException as an unchecked one. 
* 
* @param throwable to cast 
* @param <T>  the type of the Throwable 
* @return this method will never return a Throwable instance, it will just throw it. 
* @throws T the throwable as an unchecked throwable 
*/ 
@SuppressWarnings("unchecked") 
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T { 
    throw (T) throwable; // rely on vacuous cast 
} 
+0

如果您想将检查的异常转换为运行时异常,将需要添加另一个catch子句以获得代码编译... –

0

有一种模式我已经看过几次来处理这种情况。你让handleException方法声明它返回一个异常。这只是指示性的,但它永远不会返回任何东西,它总是会抛出,就像以前一样。声明的返回类型将允许调用者使用throw handleException()语句,这将使编译器保持高兴。由此产生的代码将为:

public String getXYZ(String input) throws Exception { 
    try { 
     return getFromDAO(input); 
    } catch (Exception e) { 
     throw handleException(e); 
    } 
} 

/** 
* This method will never return normally, always throws. 
*/ 
private Exception handleException(Exception e) throws Exception 
{ 
    try { 
     throw e; 
    } catch(SomeException se) { 
     throw new MyRuntimeException("MyException message", se); 
    } catch(SomeOtherException soe) { 
     throw new MyRuntimeException("MyException message", soe); 
    } 
} 
1

您可能还想考虑使用新的java 8 lambda功能来解决您的问题。您必须创建一个函数接口来声明lambda表达式的签名(以及相关的例外)。您的handleException方法现在将成为运行lambda并处理异常的人。

public String getXYZ(String input) { 
    return handleKnownExceptions(() -> getFromDAO(input)); 
} 

private <T> T handleKnownExceptions(ThrowingCode<T> throwingCode) 
{ 
    try { 
     return throwingCode.get(); 
    } catch(SomeException se) { 
     throw new MyRuntimeException("MyException message", se); 
    } catch(SomeOtherException soe) { 
     throw new MyRuntimeException("MyException message", soe); 
    } 
} 

@FunctionalInterface 
public interface ThrowingCode<T> 
{ 
    T get() throws SomeException, SomeOtherException; 
}