开发者学堂课程【Scala 核心编程-基础:异常处理】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/8939
异常处理
内容介绍
一、介绍
二、java 异常
三、Scala 异常
四、总结
一、介绍
Scala 提供 try、catch 来处理异常。try、catch 里面用于包含可能出错的代码。catch 块用于处理try块中发生的异常。那可以根据需要在程序中可以有任意数量的try、catch 块。根据需求,根据业务逻辑来确定到底需要多少个try、catch 块。
处理语法处理和 java 类似,但是又不尽相同。
二、java 异常
1.运行异常
简单回顾一下 java 的异常。在 java 中学异常处理的时候,异常有一个称之为运行时异常,还有一种叫编译时异常。其实真正的异常是指什么呢?编译只是觉得这个代码有可能抛异常。打开一个文件的时候,它指出有可能有个 IO 异常。实际上如果文件还在,其中一个异常也不会发生。准确的讲异常实际上是对这种可疑代码或者可能出错的代码进行一个处理,就不再分编译异常和运行异常了,只有一种异常,就是运行异常。
2.代码演示
新建一个小包叫 exception。为了防止这是个关键字,直接写个 myexception,要写一个 java 文件,javaExceptionDemo01。
public class JavaExceptionDemo01{
public static void main(String
[
] args){
try {
int i=0;
int b= 10;
int c=b/i
;
//执行代码时会指出 ArithmeticException 异常
}catch(Exception e){
e.printstackTrace();
}finally{
//最终要执行的代码
System.out.println("java finally");
}
System.out.println("继续执行");
假如这里有一段代码,认为这段代码很可疑,或者说可能有异常。这个时候故意制造了一个算数异常,叫ArithmeticException,用 B 去除以 I。而这个I故意给了一个零,是必然要抛异常的。这个结构是 try 里面有 catch。catch 可以有多个。finally 是最终要执行的这段代码。如果抛出了异常,e.printstackTrace()肯定会被 case。抛出异常以后,finally 始终是要执行的。这个就是 java 的一个异常处理的机制。
如果捕获了这个异常,代码就可以得到继续执行。捕获异常最主要的作用一个是把这个异常进行处理,那么代码能够保证继续执行。运行后发现继续执行是能够得到的。如果不输出这个代码,就没有出什么问题。抛出异常以后,根据业务逻辑,把这个异常进行一个再次处理就是你的业务逻辑。java 的异常处理基本上都是 try 、catch 、 finally, 这是java 异常的一个回顾。
3.java 异常的特点
(1)java 语言按照 try-catch-catch...- finally 方式来处理异常的。
(2)不管有没有捕获异常,finally 都会被执行。如果没有异常,比如 i=7,finally 也执行了。因此 finally 在 java 里面最主要的是去释放一些资源。在 try 里打开一个文件,或者是连接一个数据库,或者是得到一个 socket,往往是在finally 里面进行一个释放。
(3)可以有多个 catch,但是捕获异常的时候,要把范围小的异常写在前面,把范围大写在后面,否则编译不了。但是 Scala 可以。
public class JavaExceptionDemo01{
public static void main(Stringl] args){
try {
int i=0;
int b= 10;
int c=b/i
//执行代码时会指出 ArithmeticException 异常
}catch(ArithmeticException ex){
ex.printstackTrace();
}catch(Exception e){
e.printstackTrace();
}finally{
//最终要执行的代码
System.out.println("java finally");
}
System.out.println("继续执行");
小的异常写在前面,把大的异常写在后面,在 java 里面是支持的。如果把这个范围大的异常写在前面,把范围小的写在后面,马上就会编译出错。这个异常已经被 Exception catch。他认为这个代码是永远不可能被执行。这边一定会捕获,因为它是最大的异常,这段被捕获了,catch 就不会被捕获,写的代码没有意义,所以在 java 里面它这样写是错的。
三、Scala 异常
1.Scala 异常
try
{
Val
r=10/0
}
catch
{
c
ase
ex :ArithmeticException=>println(
“
捕获了除数为零的算数异常”)
case
ex:
Exception=>println(“捕获了异常”)
}
finally
{
//最终要执行的代码
print
l
n("scala finally..")
}
Scala 异常结构几乎跟 java 一样。但是 catch 只有一个。只有一个怎么去匹配到不同的异常?用的是 case 语句。当抛出的异常是 ArithmeticException 异常,这个异常也是来源于 java 异常。scala 异常仍然沿用了 java 异常这个体系。如果抛出一个异常匹配到 Arithmetic 就是个算术异常,就执行后面那句话。注意后面是一个代码块,是捕获到或者匹配到一个异常。箭头代表后面处理的语句。如果匹配到 Exception 就执行它的后面。最后仍然有个 finally 也是最重要执行的代码。
2.例子:
新建一个 ScalaExceptionDemo,选择 object。
Object scalaExceptionDemo{
Def main(args:Array[String]):Unit = {
try
{
v
al
r=10/0
}
catch
{
//说明
//1.在 Scala 中只有一个 catch
//2.在 catch 中有多个 case,每个 case 可以匹配到一种异常 case ex:ArithmeticException
//3.=>关键符号,表示后面是对该异常处理的处理代码块
//4.finally 最终要执行的
c
ase
ex :ArithmeticException=>println(
“
捕获了除数为零的算数异常”)
case
ex:
Exception=>println(“捕获了异常”)
}
finally
{
//最终要执行的代码
print
l
n("scala finally..")
}
}
print
l
n("
继续执行
")
}
在这个可疑代码里面,用10除以0,编译器知道肯定会抛一个异常。这个异常会被 ArithmeticException 捕获到,就会输出后面这句话,输出过后这个代码就不会被终止了。在后面写一个继续执行。运行过来可以看到捕获到这个异常了,而且 finally 也被执行了,最后继续执行。这个就是 scala 里面的一个异常捕获的一段代码。
3.Scala 异常处理小结
(1)将可疑代码封装在 try 块里面,在 try 块里面用 case 来处理这个异常。处理一个异常最主要的目的能够保证程序在出了异常过后仍然可以继续执行,不会因为一个异常发生导致整个程序崩溃。这是它最主要的一个作用。
(2)要注意 Scala 异常的工作机制跟 java 一样,但是它取消了“checked (编译期)”异常,即使 Scala 没有编译异常这个概念,所有的异常都是在运行的时候捕获处理。
(3)用关键字 throw,在做业务逻辑的时候去自定义一个异常也可以。用 throw 关键字抛出一个异常对象,所有异常都是 Throwable 的一个子类。Throw 表达式是有类型的,就是 nothing。因为 nothing 是所有子类型,所以可以把这个 throw 表达式写在任意的地方。因为抛出一个异常,而这个异常的类型又是 nothing。那就意味着任何一个变量和函数都可以去接收和处理这个异常。
例:新建一个 throwDemo,选择 object。
Object throwDemo{
def main(args Array(Stnng])
:
Unit =
{
//
val res = tes
t
()
//
printin(res
.
toString)
//如果希望在 test()抛出异常后代码可以继续执行,则需要处理
try{
test()
}catch{
case ex:Exception=>println(
“
捕获到异常”+ex.getMessage)
}finally{
}
printin(“
ok
”)
}
def test()
:
Nothing =
{
throw new Exception("
异常No1出现
"
)
}
}
可以看到 ok 是没有问题继续执行的。而且捕获到的异常就是刚才写的这个异常,将来就可以根据这个逻辑写到代码里面去。比如有段代码,跑出异常了,要去处理,可以用 try catch。
(4)在 Scala 中借用模式匹配的思想来做异常的匹配。因此 catch
代码库里面是一系列的 case 子句来捕获匹配。如果有多行,也可以换行。
(5)常捕获的机制和其他语言一样,如果有异常发生,catch 子句是按秩序来捕获的,因此 catch 子句中越具体的异常应该靠前,越不普遍的异常应该靠后。也就是范围小的往前面写,范围大的往后面写。反过来也不会报错,但是这样写是不好的编程风格。
(6)Finally 子句用于执行不管是正常处理还是异常处理都要执行的步骤。这点跟 java 一样。在 finally 里写上对try{}中的资源分配。将来去做大数据处理的时候数据是从文件里面读取的。文件要打开可能有个文件的指针,或者是引用。也有可能这个数据是从一个数据库读取的。一些资源关闭、缓存的清理等等,要在 finally 里面进行一个处理。
(7)Scala 提供了 throws 这个关键字来声明异常,可以使用方法定义声明异常,它向调用者函数提供了此方法可能引发的异常信息,有助于调用函数处理,并将该代码包含在 try catch 中,目的是避免程序异常终止。在 Scala 中可以用 throw 注释来解决一个问题。
例:throw 的声明
新建一个 ThrowComment 选择 class
Object ThrowComment{
def main(args: Array(String])
:
Unit
={
f11()
}
@throws(class
o
f[NumberFormatException
]
)
//等同于 javaNumberFormatException.class
def f11
()
=
{
"abc"
.
to
I
nt
}
}
这里用主函数 main 调用了 f11,F11用@throws 注解去声明将来可能抛出一个 NumberFormatException 这句话等同于 javaNumberFormatException.class 目的要抛出的异常,是 berFormat 这个类型。这样执行肯定就有一个异常跑出来。如果要想这个程序继续执行,在 f11那 try 就可以。看到 throw 就表示声明了,F11就会抛一个异常。
四、总结
1. 介绍
Scala 提供 try 和 catch 块来处理异常。try 块用于包含可能出错的代码。catch 块用于处理 try 块中发生的异常。可以根据需要在程序中有任意数量的 try..catch 块。
语法处理上和 Java 类似,但是又不尽相同
2.Java 异常处理回顾
public class JavaExceptionDemo01{
public static void main(Stringl] args){
try {
int i=0;
int b= 10;
int c=b/i
//执行代码时会指出 ArithmeticException 异常
}catch(Exception e){
e.printstackTrace();
}finally{
//最终要执行的代码
System.out.println("java finally");
}
System.out.println("继续执行");
3.Java 异常处理的注意点
java 语言按照 try—catch-catch...—finally 的方式来处理异常。
不管有没有异常捕获,都会执行 finally,因此通常可以在 finally 代码块中释放资源。
可以有多个 catch,分别捕获对应的异常,这时需要把范围小的异常类写在前面,把范围大的异常类写在后面,否则编译错误。会提示"Exception 'java.lang,xxxxxx' has already been caught"
4.scala 异常处理举例
Object scalaExceptionDemo{
Def main(args:Array[String]):Unit = {
try
{
v
al
r=10/0
}
catch
{
//说明
//1.在 Scala 中只有一个 catch
//2.在 catch 中有多个 case,每个 case 可以匹配到一种异常 case ex:ArithmeticException
//3.=>关键符号,表示后面是对该异常处理的处理代码块
//4.finally 最终要执行的
c
ase
ex :ArithmeticException=>println(
“
捕获了除数为零的算数异常”)
case
ex:
Exception=>println(“捕获了异常”)
}
finally
{
//最终要执行的代码
print
l
n("scala finally..")
}
}
print
l
n("
继续执行
")
}
5.Scala 异常处理小结
(1)将可疑代码封装在 try 块中。在 try 块之后使用了一个 catch 处理程序来捕获异常。如采发生任何异常,catch处理程序将处理它,程序将不会异常终止。
(2)Scala 的异常的工作机制和 Java 一样,但是 Scala 没有“checked(编译期)”异常,即 Scala 没有编译异常这个概念,异常都是在运行的时候捕获处理。
(3)用 throw 关键字,抛出一个异常对象。所有异常都是 Throwable 的子类型。throw 表达式是有类型的,就是Nothing,因为 Nothing 是所有类型的子类型,所以 throw 表达式可以用在需要类型的地方
def testO: Nothing =
{
throw new ArithmeticException("算术异常")/Exception("异常NO1出现~”)
}
(4)在 Scala 里,借用了模式匹配的思想来做异常的匹配,因此,在 catch 的代码里,是一系列 case 子句来匹配异常。当匹配上后=>有多条语句可以换行写,类似 java 的 switch case x:代码块...
(5)异常捕捉的机制与其他语言中一样,如果有异常发生,catch子 句是按次序捕捉的。因此,在 catch 子 句中,越具体的异常越要靠前,越普遍的异常越靠后,如果把越普遍的异常写在前,把具体的异常写在后,在 scala 中也不会报错,但这样是非常不好的编程风格。
(6)finally 子句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作,这点和Java 一样。
(7)Scala 提供了 throws 关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。它有助于调用函数处理并将该代码包含在 try-catch 块中,以避免程序异常终止。在 scala 中,可以使用 throws 注释来声明异常
def main(args Array[St
rin
g]) Unit ={
f11()
@throws(classOf[NumberFormatExceptionJ)y/等同于 NumberFormatException class
def f11() ={
"abc",tolnt