java中无法推断类型参数_Java中的推断异常

java中无法推断类型参数

借用和窃取其他语言的概念和想法总是很高兴的。 Scala的Option是我真正喜欢的一个主意,因此我用Java编写了一个实现。 它包装了一个可能为null或不为null的对象,并提供了一些可用于某种分类功能的方法。 例如,isDefined方法添加了一种检查值是否为null的面向对象的方法。 然后在其他地方使用它,例如getOrElse方法,该方法基本上说“给我您要包装的内容,如果没有,则回退”。

public T getOrElse(T fallback)
{
    return isDefined() ? get() : fallback;
}

实际上,这将替代传统的Java,例如

public void foo()
{
    String s = dao.getValue();
    if (s == null)
    {
        s = 'bar';
    }
    System.out.println(s);
}

与更简洁和面向对象

public void foo()
{
    Option<String> s = dao.getValue();
    System.out.println(s.getOrElse('bar'));
}

但是,如果我想做一个除获得后备值之外的事情-抛出异常,该怎么办? 更重要的是,如果我想抛出特定类型的异常(即使用时特定且未硬编码到Option中)怎么办? 这需要一点技巧,并且要进行类型推断。

因为这是Java,所以我们可以从一个新工厂– ExceptionFactory开始。 这是一个基本的实现,仅创建使用消息构造的异常,但是您当然可以根据需要扩展代码。

public interface ExceptionFactory <E extends Exception>
{
    E create(String message);
}

注意<E extended Exception> -这是它如何工作的关键。 使用工厂,我们现在可以向Option添加新方法:

public <E extends Exception> T getOrThrow(ExceptionFactory<E> exceptionFactory,
                                          String message) throws E
{
    if (isDefined())
    {
        return get();
    }
    else
    {
        throw exceptionFactory.create(message);
    }
}

同样,请注意引发E –这是从异常工厂推断出来的。

不管您信不信,这就是所需费用的90%。 一种烦恼是需要异常工厂。 如果您能忍受这一切,那么一切都准备就绪。 让我们定义几个自定义异常,以了解实际情况。

public <E extends Exception> T getOrThrow(ExceptionFactory<E> exceptionFactory,
                                          String message) throws E
{
    if (isDefined())
    {
        return get();
    }
    else
    {
        throw exceptionFactory.create(message);
    }
}

和可疑的ExceptionB类似

public class ExceptionB extends Exception
{
    public ExceptionB(String message)
    {
        super(message);
    }

    public static ExceptionFactory<ExceptionB> factory()
    {
        return new ExceptionFactory<ExceptionB>()
        {
            @Override
            public ExceptionB create(String message)
            {
                return new ExceptionB(message);
            }
        };
    }
}

最后,将它们放在一起:

public class GenericExceptionTest
{
    @Test(expected = ExceptionA.class)
    public void exceptionA_throw() throws ExceptionA
    {
        Option.option(null).getOrThrow(ExceptionA.factory(),
                                       "Some message pertinent to the situation");
    }

    @Test
    public void exceptionA_noThrow() throws ExceptionA
    {
        String s = Option.option("foo").getOrThrow(ExceptionA.factory(),
                                                   "Some message pertinent to the situation");
        Assert.assertEquals("foo",
                            s);
    }

    @Test(expected = ExceptionB.class)
    public void exceptionB_throw() throws ExceptionB
    {
        Option.option(null).getOrThrow(ExceptionB.factory(),
                                       "Some message pertinent to the situation");
    }

    @Test
    public void exceptionB_noThrow() throws ExceptionB
    {
        String s = Option.option("foo").getOrThrow(ExceptionB.factory(),
                                                   "Some message pertinent to the situation");
        Assert.assertEquals("foo",
                            s);
    }
}

如上以粗体突出显示的,需要注意的重要一点是方法签名中声明的异常是特定的–它不是共同的祖先(Exception或Throwable)。 这意味着您现在可以在任何地方的DAO层,服务层中使用“选项”,并在需要的地方和方式中抛出特定的异常。

下载源 :您可以从此处获取源代码和测试– Genex

边注
编写此文档后产生的另一件有趣的事情是观察到可以执行此操作:

public void foo()
{
    throw null;
}

public void bar()
{
    try
    {
        foo();
    }
    catch (NullPointerException e)
    {
        ...
    }
}

不用说,这不是一个好主意。

参考: Objectify博客上的JCG合作伙伴 Steve Chaloner 推断出Java中的异常

翻译自: https://www.javacodegeeks.com/2013/01/inferred-exceptions-in-java.html

java中无法推断类型参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值