[英]Java - Return statement and thrown exception using method inside catch block?
我有以下代码使用hibernate在错误时引发自定义异常,在这种情况下,我也想关闭会话,因为除非在客户端计算机上收到该异常,否则不会捕获该异常。
public <T> T get(final Session session, final String queryName) throws RemoteException
{
final Query query = // query using given session ...
try
{
return (T) query.uniqueResult();
}
catch (final HibernateException e)
{
SessionManager.logger.log(Level.SEVERE, "Could not retrieve Data", e);
this.closeSession(session);
throw new RemoteException("Could not retrieve Data");
}
}
现在,我有一个帮助程序方法,该方法关闭会话并引发给定的异常:
public void closeSessionAndThrow(final Session session, final RemoteException remoteException)
throws RemoteException
{
this.closeSession(session);
throw remoteException;
}
现在我想可以使用以下方法简化上面的代码:
public <T> T get(final Session session, final String queryName) throws RemoteException
{
final Query query = // query using given session ...
try
{
return (T) query.uniqueResult();
}
catch (final HibernateException e)
{
SessionManager.logger.log(Level.SEVERE, "Could not retrieve Data", e);
this.closeSessionAndThrow(session, new RemoteException("Could not retrieve Data"));
}
}
现在,我需要添加一个return null;
声明后抓住。 为什么?
更改closeSessionAndThrow
的声明以返回RemoteException
,然后“抛出”在客户端代码中调用它的返回结果。
public RemoteException closeSessionAndThrow( ... ) // <-- add return type here
throws RemoteException { ... }
public <T> T get( ... ) throws RemoteException
{
try { ... }
catch (final HibernateException e)
{
throw this.closeSessionAndThrow( ... ); // <-- add "throw" here
}
}
这欺骗了编译器,使之认为它将始终抛出closeSessionAndThrow
返回的任何异常。 由于helper方法本身会引发该异常,因此第二次throw
永远不会起作用。 尽管可以从帮助程序返回异常,但是当有人忘记在调用之前添加throw
时,这会引发错误。
这是closeSessionAndThrow
方法所存在的问题。 JLS规则不允许编译器推断,由于该方法无条件地引发异常,因此它永远无法正常返回。 因此,必须将调用代码编写为好像该方法可以返回...,即使“我们知道”它不可能发生。
您只需要顺其自然。 这是Java语言不像您/我们所希望的那样“不寻常”的控制模式。
(在某些情况下,可以证明该方法在某些假设下始终会引发异常。但是,由于该方法是public
并且在不同的类中,因此,其中一种假设是定义和使用该方法的类不会可以相互独立地进行更改和编译,当然,这不是编译器可以做出的那种假设,并且可以部分解释JLS规则为何不尝试覆盖此模式的原因。
如果他们要“解决”此问题,则将需要注解之类的内容,或者更改为Java语法以声明helper方法无法返回。)
尽管closeSessionAndThrow总是抛出远程异常,但是编译器不会深入方法中找出异常,因此,编译器仅知道它可以抛出RemoteException,而不会知道。 我可能会做这样的事情:
public RemoteException closeSessionAndThrow(final Session session, final Exception e, String msg)
{
SessionManager.logger.log(Level.SEVERE, msg, e);
this.closeSession(session);
return new RemoteException(msg);
}
public <T> T get(final Session session, final String queryName) throws RemoteException
{
final Query query = // query using given session ...
try
{
return (T) query.uniqueResult();
}
catch (final HibernateException e)
{
throw this.closeSessionAndThrow(session, e, "Could not retrieve Data");
}
}
由于此方法必须返回某些内容,因此应将return null;
后
this.closeSessionAndThrow(session, new RemoteException("Could not retrieve Data"));
但仍在catch
子句中或使用finally
子句。
为什么需要这样做? 因为您的函数必须返回某些内容。 从一开始它就从:
this.closeSessionAndThrow(session, new RemoteException("Could not retrieve Data"));
并且不返回任何内容,这会导致编译器错误。
最终添加到try-catch块中,最终{返回null; }-如果执行进入try块,结果为成功,它将返回,因此最终将永远不会执行。 -如果执行进入catch块,则finally块在catch之后执行,并将返回null。 安全执行!
答案不正确!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.