Java中的推断异常
借用和竊取其他語(yǔ)言的概念和想法總是很高興的。 Scala的Option是我真正喜歡的一個(gè)主意,因此我用Java編寫了一個(gè)實(shí)現(xiàn)。 它包裝了一個(gè)可能為null或不為null的對(duì)象,并提供了一些可按某種功能使用的方法。 例如,isDefined方法添加了一種面向?qū)ο蟮姆绞絹?lái)檢查值是否為null。 然后在其他地方使用它,例如getOrElse方法,該方法基本上說(shuō)“給我您要包裝的內(nèi)容,如果沒有,則回退”。
實(shí)際上,這將替代傳統(tǒng)的Java,例如
public void foo() {String s = dao.getValue();if (s == null){s = 'bar';}System.out.println(s); }與更簡(jiǎn)潔和面向?qū)ο?
public void foo() {Option<String> s = dao.getValue();System.out.println(s.getOrElse('bar')); }但是,如果我想做一個(gè)除獲得后備值之外的事情-拋出異常,該怎么辦? 更重要的是,如果我要拋出特定類型的異常(即使用中特定且未硬編碼到Option中)怎么辦? 這需要一點(diǎn)技巧,并需要進(jìn)行類型推斷。
因?yàn)檫@是Java,所以我們可以從一個(gè)新工廠– ExceptionFactory開始。 這是一個(gè)基本的實(shí)現(xiàn),僅創(chuàng)建使用消息構(gòu)造的異常,但是您當(dāng)然可以根據(jù)需要擴(kuò)展代碼。
public interface ExceptionFactory <E extends Exception> {E create(String message); }注意<E extended Exception> –這是它如何工作的關(guān)鍵。 使用工廠,我們現(xiàn)在可以向Option添加新方法:
public <E extends Exception> T getOrThrow(ExceptionFactory<E> exceptionFactory,String message) throws E {if (isDefined()){return get();}else{throw exceptionFactory.create(message);} }同樣,請(qǐng)注意引發(fā)E –這是從異常工廠推斷出來(lái)的。
不管您信不信,這就是所需費(fèi)用的90%。 一種煩惱是需要異常工廠。 如果您能忍受這一切,那么一切都準(zhǔn)備就緒。 讓我們定義幾個(gè)自定義異常,以了解實(shí)際情況。
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>(){@Overridepublic 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");}@Testpublic 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");}@Testpublic void exceptionB_noThrow() throws ExceptionB{String s = Option.option("foo").getOrThrow(ExceptionB.factory(),"Some message pertinent to the situation");Assert.assertEquals("foo",s);} }如上以粗體突出顯示的那樣,需要注意的重要一點(diǎn)是方法簽名中聲明的異常是特定的–它不是共同的祖先(Exception或Throwable)。 這意味著您現(xiàn)在可以在任何地方的DAO層,服務(wù)層中使用“選項(xiàng)”,并在需要的地方和方式中拋出特定的異常。
下載源 :您可以從此處獲取源代碼和測(cè)試– Genex
邊注
編寫此書后產(chǎn)生的另一件有趣的事情是觀察到可以執(zhí)行此操作:
不用說(shuō),這不是一個(gè)好主意。
參考: Objectify博客上的JCG合作伙伴 Steve Chaloner 推斷出Java中的異常 。
翻譯自: https://www.javacodegeeks.com/2013/01/inferred-exceptions-in-java.html
總結(jié)
以上是生活随笔為你收集整理的Java中的推断异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 包用英语怎么说 包的英语是什么
- 下一篇: 寓意钱多的名字 寓意钱多的名字有哪些