Java force catch RuntimeException?

时间:2010-04-30 04:10:54

标签: java exception-handling

是否可以强制java让你捕获RuntimeExceptions?具体来说,我正在使用Spring框架,整个异常层次结构基于RuntimeExceptions。很多时候我忘记尝试捕捉异常。一个具体的例子是在进行LDAP查询或SQL调用时。

9 个答案:

答案 0 :(得分:7)

不仅仅是Java。

但是如果使用AspectJ编译器进行编译或使用AspectJ加载时编织修改类,则可能。

来自Wikipedia的方面的定义:

  

一个方面是程序的一部分   交叉削减其核心问题

方面通常用于添加例如事务和安全逻辑。

为了演示方面如何解决您的问题,我创建了一个示例,该示例捕获从标记有@Service批注的类中的方法内部调用集成层后抛出的所有异常。在这种情况下,包名称中包含.integration.的类。

这只是一个例子。您可以修改它以捕获其他地方的RuntimeExceptions。例如,在名称中包含Facade并调用其他方法的类中的所有方法中。请参见下面的图片:

alt text http://files.espenberntsen.net/stackoverflow/call-to-integration-layer.png 橙色箭头是我用Eclipse中的AJDT插件说明的AspectJ切入点。这是您可以在AfterThrowing建议中捕获和处理运行时异常的地方。

以下是建议:

@AfterThrowing(value="serviceMethodAfterExpcetionFromIntegrationLayerPointcut()",     
     throwing="e")
public void serviceMethodAfterExceptionFromIntegrationLayer(JoinPoint joinPoint,
  RuntimeException e) {
  StringBuilder arguments = generateArgumentsString(joinPoint.getArgs());

  logger.error("Error in service " + joinPoint.getSignature()
  + " with the arguments: " + arguments, e);
  }

我的serviceMethodAfterExpcetionFromIntegrationLayerPointcut实际包含两个其他的poincuts:

 @Pointcut("call(* *..integration.*.*(..))")
 public void integrationLayerPointcut() {}

 @Pointcut("within(@org.springframework.stereotype.Service *)")
 public void serviceBean() {}

 @Pointcut("serviceBean() && integrationLayerPointcut()")
 public void serviceMethodAfterExpcetionFromIntegrationLayerPointcut() {}

简短总结,切入点查找标有@Service注释的类中的所有位置,这些注释调用集成层上的类中的方法。 (见图中的橙色箭头)

如果要在测试类中捕获运行时异常,可以将切入点更改为:

@Pointcut("within(com.redpill.linpro.demo..*Test)")
public void inDemoProjectTestClass() {}

然后上面的建议将捕获在.demo包中以Test结尾的测试类中的所有异常。

有关@AspectJ style here的更多信息。

AspectJ与Spring完美集成。可以找到有关AspectJ的一般信息here和Spring的AspectJ支持here

答案 1 :(得分:5)

否:RuntimeException及其子类是未经检查的例外。

JLS 11.2.5 Why Runtime Exceptions are not Checked

  

运行时异常类(RuntimeException及其子类)免于编译时检查,因为在Java编程语言的设计者的判断中,必须声明此类异常不会有助于确定计划的正确性。 Java编程语言的许多操作和构造都可能导致运行时异常。编译器可用的信息以及编译器执行的分析级别通常不足以确定不会发生此类运行时异常,即使这对程序员来说可能是显而易见的。要求声明这样的异常类只会让程序员感到恼火。

JLS 11.5 The Exception Hierarchy

  

Exception是普通程序可能希望从中恢复的所有异常的超类。类RuntimeException是类Exception的子类。 RuntimeException的子类是未经检查的异常类。除Exception以外的RuntimeException及其子类的子类都是已检查的异常类。

答案 2 :(得分:2)

没有。永远不会检查RuntimeException的子类。

答案 3 :(得分:1)

实际上,出于充分的原因,Spring异常是运行时的。 Spring将已检查的异常转换为运行时,因为例如,如果由于数据库关闭而抛出SQLException,则您不太可能恢复或执行有意义的操作。

此外,通过检查异常,您的代码变得更加纠结和笨拙,特别是如果您必须在catch块中有另一个try / catch块。

答案 4 :(得分:0)

不,你不能强迫编译器让你抓住任何RuntimeException

基本上因为您调用的方法没有声明它抛出RuntimeException,编译器无法知道可能抛出的任何异常,或者强迫您捕获它们。

答案 5 :(得分:0)

不,那是不可能的。

你可以做什么,但设计不好而且绝对不推荐,是你让方法抛出Exception

public void doStuff() throws Exception {}

因此强制任何调用者捕获Exception。这包括RuntimeException,但这是一个糟糕的设计,因为范围非常广泛,并没有指定抛出的异常。

答案 6 :(得分:0)

没有。我唯一能想到的是使用像FindBugs,PMD等工具来为你找到这些问题,尽管我不相信这两种工具都有特定的工具。但是你可以编写自己的探测器。当然,这只适用于显式抛出RuntimeExceptions,而不是隐式抛出,如NullPointerException。

答案 7 :(得分:0)

我不鼓励你记住在任何地方都能抓住所有有趣的例外,我鼓励为一些春季电话编写一个包装器。

所以不要被迫记住

 try {
    SpringThing.doThatOneMethod();
 catch (SpringConnectionException sce) { /*handle it*/ }
 catch (SpringProxyException      spe) { /*handle it*/ }
 catch (SpringRuntimeException    sre) { /*handle it*/ }

,您可以随时调用自己的SpringExceptionsWrapper.doThatOneMethod()

如果你真的想要,你可以让你的包装函数的方法签名列出一些你可能包装内容的已检查异常。我不鼓励它,因为它迫使你在任何地方正确处理它。

答案 8 :(得分:0)

RuntimeExceptions可以像Checked Exceptions一样被捕获和处理,但不必处理它们。例如,如果在try块中抛出新的NullPointerException(),编译器将不会强制您在抛出Checked Exception时将throws关键字放在方法声明中。 处理RuntimeException或其子类表示编程风格错误,应该避免使用。