任何编程语言都需要异常处理来处理运行时错误,以便可以维持应用程序的正常运行
让我们考虑以下程序,该程序对名为Example.txt的文件进行操作。但是,始终可能存在文件Example.txt不存在的情况。
(ns clojure.examples.example (:gen-class)) ;; This program displays Hello Learnfk (defn Example [] (def string1 (slurp "Example.txt")) (println string1)) (Example)
如果文件Example.txt不存在,则程序将生成以下异常。
Caused by: java.io.FileNotFoundException: Example.txt (No such file or directory) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at clojure.java.io$fn__9185.invoke(io.clj:229) at clojure.java.io$fn__9098$G__9091__9105.invoke(io.clj:69) at clojure.java.io$fn__9197.invoke(io.clj:258) at clojure.java.io$fn__9098$G__9091__9105.invoke(io.clj:69)
从上面的异常中,我们可以清楚地看到该程序引发了FileNotFoundException。
一种经典的情况是ArrayIndexOutOfBoundsException,当您尝试访问大于数组长度的数组索引时会发生这种情况。以下是这种错误的典型示例。
(ns clojure.examples.example (:gen-class)) (defn Example [] (try (aget (int-array [1 2 3]) 5) (catch Exception e (println (str "caught exception: " (.toString e)))) (finally (println "This is our final block"))) (println "Let's move on")) (Example)
执行以上代码时,将引发以下异常。
caught exception: java.lang.ArrayIndexOutOfBoundsException: 5 This is our final block Let's move on
错误是无法恢复的,如OutOfMemoryError,VirtualMachineError,AssertionError等。这些是程序永远无法恢复的错误,将导致程序崩溃。现在,我们需要某种机制来捕获这些异常,以便如果存在这些异常,则程序可以继续运行。
下图显示了Clojure中异常的层次结构是如何组织的。全部基于Java中定义的层次结构。
与其他编程语言一样,Clojure提供了正常的" try-catch"块来在异常发生时捕获异常。
以下是try-catch块的一般语法。
(try (//Protected code) catch Exception e1) (//Catch block)
在 catch块中,您可以编写自定义代码来处理异常,以便应用程序可以从异常中恢复。
让我们看一下前面的示例,该示例生成了一个文件未找到的异常,并了解了如何使用try catch块来捕获程序引发的异常。
(ns clojure.examples.example (:gen-class)) (defn Example [] (try (def string1 (slurp "Example.txt")) (println string1) (catch Exception e (println (str "caught exception: " (.getMessage e)))))) (Example)
上面的程序产生以下输出。
caught exception: Example.txt (No such file or directory)
从上面的代码,我们将错误的代码包装在 try块中。在catch块中,我们只是捕获我们的异常并输出一条消息,说明发生了异常。
一个可以有多个catch块来处理多种类型的异常。对于每个catch块,根据引发的异常类型,您将编写相应的代码来处理它。
让我们修改一下先前的代码,使其包含两个catch块,一个专门针对我们的文件未找到异常,另一个专门针对一般异常块。
(ns clojure.examples.example (:gen-class)) (defn Example [] (try (def string1 (slurp "Example.txt")) (println string1) (catch java.io.FileNotFoundException e (println (str "caught file exception: " (.getMessage e)))) (catch Exception e (println (str "caught exception: " (.getMessage e))))) (println "Let's move on")) (Example)
上面的程序产生以下输出。
caught file exception: Example.txt (No such file or directory) Let's move on
从上面的输出中,我们可以清楚地看到,我们的异常是由" FileNotFoundException" catch块而不是常规块捕获的。
finally块位于try块或catch块之后。无论是否发生异常,始终都会执行一个finally代码块。
通过使用finally块,无论受保护代码发生什么情况,您都可以运行要执行的任何清理类型的语句。
(try (//Protected code) catch Exception e1) (//Catch block) (finally //Cleanup code)
让我们修改上面的代码,并添加代码的finally块。
(ns clojure.examples.example (:gen-class)) (defn Example [] (try (def string1 (slurp "Example.txt")) (println string1) (catch java.io.FileNotFoundException e (println (str "caught file exception: " (.getMessage e)))) (catch Exception e (println (str "caught exception: " (.getMessage e)))) (finally (println "This is our final block"))) (println "Let's move on")) (Example)
上面的程序产生以下输出。
caught file exception: Example.txt (No such file or directory) This is our final block Let's move on
从上面的程序中,您可以看到在catch块捕获所需的异常之后,也实现了final块。
以下是使用上面列出的某些方法的示例代码。
(ns clojure.examples.example (:gen-class)) (defn Example [] (try (def string1 (slurp "Example.txt")) (println string1) (catch java.io.FileNotFoundException e (println (str "caught file exception: " (.toString e)))) (catch Exception e (println (str "caught exception: " (.toString e)))) (finally (println "This is our final block"))) (println "Let's move on")) (Example)
上面的程序产生以下输出。
caught file exception: java.io.FileNotFoundException: Example.txt (No such file or directory) This is our final block Let's move on
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)