
因果推断
借用和窃取其他语言的概念和想法总是很高兴的。 Scala的Option是我真正喜欢的一个想法,因此我用Java编写了一个实现。 它包装了一个可能为null或不为null的对象,并提供了一些可按某种功能使用的方法。 例如,isDefined方法添加了一种检查值是否为null的面向对象的方法。 然后在其他地方使用它,例如getOrElse方法,该方法基本上说“给我您要包装的内容,如果没有,则回退”。
1
2
3
4public T getOrElse(T fallback) { return isDefined() ? get() : fallback; }
实际上,这将替代传统的Java,例如
1
2
3
4
5
6
7
8
9public void foo() { String s = dao.getValue(); if (s == null) { s = 'bar'; } System.out.println(s); }
与更简洁和面向对象
1
2
3
4
5public void foo() { Option<String> s = dao.getValue(); System.out.println(s.getOrElse('bar')); }
但是,如果我想做一个除获得后备值以外的事情怎么办–比如抛出一个异常? 更重要的是,如果我要抛出特定类型的异常(即使用时特定且未硬编码到Option中)怎么办? 这需要一点技巧,并且要进行类型推断。
因为这是Java,所以我们可以从一个新工厂– ExceptionFactory开始。 这是一个基本的实现,它仅创建使用消息构造的异常,但是您当然可以根据需要扩展代码。
1
2
3
4public interface ExceptionFactory <E extends Exception> { E create(String message); }
注意<E extended Exception> –这是它如何工作的关键。 使用工厂,我们现在可以向Option中添加新方法:
1
2
3
4
5
6
7
8
9
10
11
12public <E extends Exception> T getOrThrow(ExceptionFactory<E> exceptionFactory, String message) throws E { if (isDefined()) { return get(); } else { throw exceptionFactory.create(message); } }
同样,请注意引发E –这是从异常工厂推断出来的。
不管您信不信,这就是所需费用的90%。 一种烦恼是需要异常工厂。 如果您能忍受这一切,那么一切都准备就绪。 让我们定义几个自定义例外,以了解实际情况。
1
2
3
4
5
6
7
8
9
10
11
12public <E extends Exception> T getOrThrow(ExceptionFactory<E> exceptionFactory, String message) throws E { if (isDefined()) { return get(); } else { throw exceptionFactory.create(message); } }
和可疑的ExceptionB类似
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public 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); } }; } }
最后,将它们放在一起:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public 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
边注撰写此书的另一件有趣的事情是观察到可以执行此操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public 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中的推断异常的全部内容,更多相关因果推断_Java中内容请搜索靠谱客的其他文章。
发表评论 取消回复