有一种方法来注释的方法,从而抛出被转换为运行时异常所有异常自动的?

@MagicAnnotation
// no throws clause!
void foo()
{
  throw new Exception("bar")'
}
有帮助吗?

解决方案

没有办法做到这一点,至少在目前我使用的解决方法是这样的(简化的):

@SuppressWarnings({"rawtypes", "unchecked"})
public class Unchecked {
    public static interface UncheckedDefinitions{
        InputStream openStream();
        String readLine();
            ...
    }

  private static Class proxyClass = Proxy.getProxyClass(Unchecked.class.getClassLoader(), UncheckedDefinitions.class);

    public static UncheckedDefinitions unchecked(final Object target){
        try{
            return (UncheckedDefinitions) proxyClass.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler(){
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (target instanceof Class){
                        return MethodUtils.invokeExactStaticMethod((Class) target, method.getName(), args);
                    }

                  return MethodUtils.invokeExactMethod(target, method.getName(), args);
                }
            });
        }
        catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}

和使用如下:

import static ....Unchecked.*;

...

Writer w = ...;
unchecked(w).write(str, off, len);

诀窍是,接口“没有完成”每次我需要选中方法的地方,我会换行对象为未选中状态,让IDE生成的接口方法的签名。

实现为通用然后(反射和“慢”,但通常足够快)

有一些代码后处理器并字节码织布,但这是不可能的(甚至没有AOP或其他基于JVM的语言),我目前的项目,所以这是“发明”。

其他提示

项目龙目岛的 @SneakyThrows 可能是你在找什么。是不是真的包装你的异常(因为它可以在很多情况下的问题),它只是没有在编译过程中抛出一个错误。

@SneakyThrows
void foo() {
    throw new Exception("bar")'
}

您可以使用AspectJ做到这一点。声明一个连接点(在方法FOO的这种情况下调用)和“软化”的异常。

修改要阐述这一点:

说您有下面的类Bar

public class Bar {

    public void foo() throws Exception {
    }
}

...和你有一个这样的试验:

import junit.framework.TestCase;

public class BarTest extends TestCase {

    public void testTestFoo() {
        new Bar().foo();
    }
}

那么显然该测试是不会编译。这将给出错误:

Unhandled exception type Exception  BarTest.java(line 6)

现在来克服这个和AspectJ,你写一个非常简单的方面:

public aspect SoftenExceptionsInTestCode {

    pointcut inTestCode() : execution(void *Test.test*());

    declare soft : Exception : inTestCode();
}

在方面基本上说,从一测试中的任何代码(即:与在“测试”结尾的一类“测试”并启动一个方法返回“无效”)抛出异常应该由AspectJ被接受编译器。如果发生异常,它将被包裹并抛出由AspectJ编译一个RuntimeException

事实上,如果你在Eclipse中运行这个测试作为一个AspectJ项目的一部分(用AJDT安装),然后测试会成功,而无需方面它甚至不会编译。

我认为这是可能的字节码的重新设计,定制的编译器或也许面向方面的编程 1 。在相反的对Java,C#仅具有强制异常 2

我可以问你为什么要打压检查的异常?

1 根据马腾Winkels 这是可能的。结果 2 和它们正在考虑引入检查的,根据一些9频道的视频。

编辑:对于这样的问题:这是可能的,你可以注释你的方法来标记他们是经过检查的异常抑制候选人感。然后你使用一些编译时或运行伎俩应用的实际抑制/包装。

不过,我没有看到你周围的情况下,环境,包装在这些方面可能会混淆该方法的客户例外 - 他们可能没有准备好应对一个RuntimeException。例如:在方法抛出IOException异常和您的客户抓住它作为FileNotFoundException异常显示一个错误对话框。不过,如果你换你的例外成一个RuntimeException,错误对话框被从未显示,可能它杀死调用程序线程太多。 (IMHO)。

在经过例外是该方法的实施责任。 采取非常非常小心这个事实。如果你不使用的解决办法文物这样的。

您可以通过使用的事实,Class.newInstance的包通过在Exception无参数的构造函数抛出的InvocationTargetException在任何情况下做到这一点;而它抛出它默默地

class ExUtil {
  public static void throwSilent(Exception e) { //NOTICE NO THROWS CLAUSE
      tl.set(e);
      SilentThrower.class.newInstance(); //throws silently
  }

  private static ThreadLocal<Exception> tl = new ThreadLocal<Exception>();
  private static class SilentThrower {
      SilentThrower() throws Exception {
          Exception e = tl.get();
          tl.remove();
          throw e;
      }
  }
}

然后你就可以在任何地方使用这个工具:

ExUtil.throwSilent(new Exception());
//or
try {
  ioMethod();
} catch (IOException e) { ExUtil.throwSilent(e); }

顺便说一句,这是一个非常糟糕的主意: - )

我使用Eclipse的完成/模板系统来容易地包裹的任何代码块。

下面是我的模板:

try { // Wrapp exceptions

${line_selection}${cursor}

} catch (RuntimeException e) { // Forward runtime exception
throw e;
} catch (Exception e) { // Wrap into runtime exception
throw new RuntimeException(
    "Exception wrapped in #${enclosing_method}", 
    e); 
}

使用的Java 8很容易,因为:soften(() -> methodThatMayThrow())

更多详情 HTTP://iirekm.blogspot的.com / 2014/05 / FIX-问题与 - java的checked.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top