抑制java对修饰符的检查_Java 7对抑制异常的支持
抑制java對(duì)修飾符的檢查
在JDK 7中 ,向Throwable類( Exception和Error類的父類)添加了一個(gè)新的構(gòu)造函數(shù)和兩個(gè)新方法。 添加了新的構(gòu)造函數(shù)和兩個(gè)新方法以支持“抑制的異常”(不要與吞咽或忽略異常的不良做法相混淆)。 在本文中,我將探討為什么引入這些方法以及它們?cè)贘DK 7中的使用方式。我簡(jiǎn)短討論了抑制異常與鏈?zhǔn)疆惓5牟煌帯?被抑制的異常在新的Java 7 try-with-resources語(yǔ)句 (也稱為自動(dòng)資源管理 [ ARM ])的執(zhí)行中起著重要作用。 為這種新的資源管理功能提供API支持似乎已成為Throwable類上新的構(gòu)造函數(shù)和方法的主要驅(qū)動(dòng)程序,該類提供了對(duì)抑制異常的訪問,但是API支持在try-with-resources語(yǔ)句之外使用抑制異常。 。
遇到被抑制的異常的最常見用例是,當(dāng)try-with-resources語(yǔ)句(這是一種嘗試類型,根據(jù)Java語(yǔ)言規(guī)范Java SE 7 Edition 14.20 ,它不需要catch或finally子句時(shí))遇到一個(gè)異常。 try塊中的異常,然后在隱式嘗試關(guān)閉相關(guān)資源時(shí)遇到另一個(gè)異常。
為了說明這種情況,我組成了自己的“資源”,可以在try-with-resource語(yǔ)句中使用它,因?yàn)樗鼘?shí)現(xiàn)了java.lang.AutoCloseable接口。 當(dāng)使用它的代碼嘗試使用它時(shí),此“頑皮資源”會(huì)故意引發(fā)異常,然后在調(diào)用重寫的close方法(由AutoCloseable接口指定的唯一方法)時(shí)引發(fā)另一個(gè)異常,從而繼續(xù)其不良形式。 接下來顯示NaughtyResource的代碼清單。
NaughtyResource.java
package dustin.examples;/*** Resource that throws exceptions both in its use and its closure and is only* intended for use in demonstrating Java 7's suppressed exceptions APIs. This* is not a well-behaved class.* * @author Dustin*/ public class NaughtyResource implements AutoCloseable {/*** Method that intentionally throws an exception.* * @throws RuntimeException Thrown no matter how you call me.*/public void doNothingGood(){throw new RuntimeException("Nothing good can come of this.");}/*** The overridden closure method from AutoCloseable interface.* * @throws Exception Exception that might be thrown during closure of this* resource.*/@Overridepublic void close() throws Exception{throw new UnsupportedOperationException("Not supported yet.");} }現(xiàn)在有了頑皮的資源,是時(shí)候使用頑皮的資源并演示抑制異常API。 下一張圖像描述了如果嘗試使用該資源而不捕獲close方法隱式拋出的Exception且未聲明該方法拋出該異常的情況。
這是javac提供的錯(cuò)誤消息,如以下屏幕快照所示。
我已經(jīng)顯示了前兩個(gè)屏幕快照,以強(qiáng)調(diào)對(duì)資源執(zhí)行的隱式關(guān)閉調(diào)用。 NetBeans編輯器和控制臺(tái)中顯示的錯(cuò)誤消息清楚地表明了這種情況。
下一個(gè)代碼清單包含編譯的SuppressedExceptions類的第一個(gè)版本。
SuppressedExceptions.java(版本1)
package dustin.examples;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/ public class SuppressedExceptions {/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments) throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();}} }盡管在執(zhí)行上述代碼時(shí)確實(shí)遇到了兩個(gè)異常(一個(gè)在NaughtyResource.doNothingGood()調(diào)用的try塊內(nèi),一個(gè)在隱式調(diào)用close方法的調(diào)用中),但只有一個(gè)滲透到頂部,并在應(yīng)用程序顯示時(shí)顯示。運(yùn)行。 下一個(gè)屏幕快照對(duì)此進(jìn)行了演示。
如最后一張圖片所示,僅顯示try-with-resources語(yǔ)句的try try塊中遇到的異常。 在這里,可以向Throwable(在這種情況下為Exception)詢問其受抑制的異常的功能非常有用。 為了證明這一點(diǎn),接下來顯示SuppressedExceptions類的版本2(使用Throwable.getSuppressed() )。
SuppressedExceptions.java(版本2)
package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/ public class SuppressedExceptions {/*** Method that uses NaughtyResource with try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the* NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();} }/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{performTryWithResource();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}}} }上面的應(yīng)用程序?qū)⒋蛴〕鏊幸种频漠惓!?在這種情況下,嘗試關(guān)閉NaughtyResource時(shí)遇到的異常現(xiàn)在顯示為被抑制的異常之一。 下一個(gè)屏幕快照對(duì)此進(jìn)行了演示。
如Java教程中所述,我們看到唯一拋出的異常是在try-with-resources語(yǔ)句的try塊中遇到的異常,并且在資源關(guān)閉期間遇到的第二個(gè)異常被“抑制”(但仍可從實(shí)際拋出異常)。
不需要使用try-with-resources來處理抑制的異常。 下一個(gè)代碼清單將SuppressedExceptions改編為使用更傳統(tǒng)的try-finally。
SuppressedExceptions.java(版本3)
package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/ public class SuppressedExceptions {/*** Method that uses NaughtyResource with JDK 7 try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the* NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();} }/*** Method that uses NaughtyResource with traditional try-finally statement.* * @throws Exception Exception thrown during use of NaughtyResource.*/public static void performTryFinally() throws Exception{final NaughtyResource naughty = new NaughtyResource();try{naughty.doNothingGood();}finally{naughty.close();}}/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{ // performTryWithResource();performTryFinally();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}else{err.println("\tNo Suppressed Exceptions.");}}} }上面的代碼調(diào)用了一種使用try-finally的方法,其行為與try-with-resources示例的行為不同,如下面的屏幕快照所示。
try-finally顯示嘗試關(guān)閉資源時(shí)遇到的異常,而不是使用資源時(shí)遇到的異常(上面顯示的try-with-resources相反)。 另一個(gè)區(qū)別是,即使在try-finally情況下,作為抑制的異常,其他異常也不可用。 這是廣為宣傳的 “ 丟失的異常 ”問題的一個(gè)示例 ,該問題可能包含潛在的“瑣碎”異常(關(guān)閉資源),而隱藏了潛在的更重要的異常(實(shí)際上是在使用資源)。
如果我想同時(shí)查看NaughtyResource的使用和關(guān)閉過程中引發(fā)的異常以及try-finally,可以使用Throwable.addSuppressed(Throwable) ,如下面的代碼清單所示。 在該清單中,對(duì)try和finally子句進(jìn)行了增強(qiáng),以捕獲在使用NaughtyResource期間引發(fā)的異常,并將捕獲的異常添加到實(shí)際拋出的異常中作為抑制的異常。
SuppressedExceptions.java(版本4)
package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/ public class SuppressedExceptions {/*** Method that uses NaughtyResource with JDK 7 try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the* NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();} }/*** Method that uses NaughtyResource with traditional try-finally statement.* * @throws Exception Exception thrown during use of NaughtyResource.*/public static void performTryFinally() throws Exception{final NaughtyResource naughty = new NaughtyResource();Throwable throwable = null;try{naughty.doNothingGood();}catch (Exception usingEx){throwable = usingEx;}finally{try{naughty.close();}catch (Exception closingEx){if (throwable != null){closingEx.addSuppressed(throwable);throw closingEx;}}}}/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{ // performTryWithResource();performTryFinally();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}else{err.println("\tNo Suppressed Exceptions.");}}} }修改后的類的輸出如下所示。 請(qǐng)注意,由于使用資源本身而導(dǎo)致的異常現(xiàn)在與作為抑制的異常而引發(fā)的異常相關(guān)聯(lián)。 盡管此處未顯示,但Throwable現(xiàn)在還提供了一個(gè)構(gòu)造函數(shù),該構(gòu)造函數(shù)允許通過布爾參數(shù)來指定是否允許(啟用)或禁止(禁止)新實(shí)例化的Throwable抑制異常。
查看抑制異常的另一個(gè)角度是完整堆棧跟蹤。 以下三個(gè)圖像是使用try-with-resources(顯式顯示假定的異常),使用傳統(tǒng)的try-finally語(yǔ)句而未顯式添加抑制的異常(因此在full stack跟蹤中沒有抑制的異常)導(dǎo)致的完整堆棧跟蹤的屏幕快照。 ,并使用傳統(tǒng)的try-finally方法,并明確添加抑制的異常(因此確實(shí)出現(xiàn)在完整堆棧跟蹤中)。 我在每個(gè)圖像上都添加了一條紅線,以單獨(dú)顯示整個(gè)堆棧跟蹤結(jié)束的地方,并在適用的情況下,圈出了對(duì)抑制異常的顯式引用。
抑制的異常與鏈接的異常
禁止的異常與鏈接的異常不同 。 鏈接異常是JDK 1.4引入的,旨在使輕松跟蹤異常之間的因果關(guān)系成為可能。 通常,鏈接的異常是由于將新引發(fā)的異常與已捕獲并導(dǎo)致引發(fā)新異常的異常相關(guān)聯(lián)而導(dǎo)致的。 例如,可能會(huì)引發(fā)未檢查的異常,從而“包裝”已捕獲的已檢查的異常,并且可以將它們鏈接在一起。
JDK 7引入了抑制異常,它與因果關(guān)系無(wú)關(guān),而與在單個(gè)拋出的異常中表示可能相關(guān)但不一定因果的多個(gè)例外條件有關(guān)。 在上面的我的頑皮資源示例中,頑皮資源在其唯一方法被調(diào)用時(shí)的異常并不是導(dǎo)致它在調(diào)用其close方法時(shí)引發(fā)異常的原因。 因此,將兩個(gè)異常關(guān)聯(lián)起來(通過抑制的異常機(jī)制)比強(qiáng)迫一個(gè)異常似乎是造成連鎖關(guān)系中另一個(gè)異常的原因更有意義。
通過比較Throwable訪問每種類型的方法,快速了解連鎖異常與抑制異常之間的區(qū)別可能是最容易的。 對(duì)于鏈?zhǔn)疆惓?#xff0c;將調(diào)用特定的Exception(Throwable)方法。 此方法返回導(dǎo)致Throwable的單個(gè)實(shí)例。 可以詢問返回的Throwable的原因,并在導(dǎo)致Throwables的整個(gè)過程中重復(fù)該過程。 重要的觀察結(jié)果是,每個(gè)給定的Throwable都有一個(gè)導(dǎo)致Throwable的原因。 這可以與Throwable在調(diào)用其getSuppressed()方法時(shí)提供多個(gè)抑制的Throwable(在數(shù)組中)的能力進(jìn)行對(duì)比。
NetBeans推薦嘗試資源
在這里值得注意的是,NetBeans會(huì)警告您嘗試使用try-finally,并建議使用try-with-resources替換它,如我在我的文章《 用于現(xiàn)代化Java代碼的七個(gè)NetBeans提示》和下面顯示的屏幕快照中所討論的。
結(jié)論
我相信很明顯,為什么NetBeans建議開發(fā)人員將對(duì)資源處理的最后嘗試更改為try-with-resources語(yǔ)句。 通常最好先了解資源上的哪個(gè)操作導(dǎo)致了異常,但是如果需要的話,也能夠在關(guān)閉時(shí)訪問異常是一件很不錯(cuò)的事情。 如果必須選擇,我通常會(huì)對(duì)執(zhí)行期間的資源問題更感興趣,因?yàn)殛P(guān)閉問題可能是該問題的衍生形式。 但是,兩者都更好。 傳統(tǒng)的try-finally最終僅列出關(guān)閉時(shí)的異常,而無(wú)需付出額外的努力來中繼這兩個(gè)異常。 try-with-resource語(yǔ)句不僅更簡(jiǎn)潔; 由于內(nèi)置支持包含抑制的異常,它也更加有用。
參考: JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客上提供了Java 7對(duì)抑制異常的支持 。
翻譯自: https://www.javacodegeeks.com/2012/04/java-7s-support-for-suppressed.html
抑制java對(duì)修飾符的檢查
總結(jié)
以上是生活随笔為你收集整理的抑制java对修饰符的检查_Java 7对抑制异常的支持的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行柜台能取新钱吗?
- 下一篇: java存储过程示例_安全密码存储–请勿