目录
异常
def main(args: Array[String]): Unit = {
try {
var n= 10 / 0
}catch {
case ex: ArithmeticException=>{
// 发生算术异常
println("发生算术异常")
}
case ex: Exception=>{
// 对异常处理
println("发生了异常 1")
println("发生了异常 2")
}
}finally {
println("finally")
}
}
1
)我们将可疑代码封装在
try
块中。在
try
块之后使用了一个
catch
处理程序来捕获异
常。如果发生任何异常,
catch
处理程序将处理它,程序将不会异常终止。
2
)
Scala
的异常的工作机制和
Java
一样,但是
Scala
没有“
checked
(编译期)”异常
,
即
Scala
没有编译异常这个概念,异常都是在运行的时候捕获处理。
3
)异常捕捉的机制与其他语言中一样,如果有异常发生,
catch
子句是按次序捕捉的。
因此,在
catch
子句中,越具体的异常越要靠前,越普遍的异常越靠后,如果把越普遍的异
常写在前,把具体的异常写在后,在
Scala
中也不会报错,但这样是非常不好的编程风格。
4
)
finally
子句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用
于对象的清理工作,这点和
Java
一样。
5
)用
throw
关键字,抛出一个异常对象。所有
异常都是
Throwable
的子类型。
throw
表
达式是有类型的,就是
Nothing
,因为
Nothing
是所有类型的子类型,所以
throw
表达式可
以用在需要类型的地方
def test():Nothing = {
throw new Exception("不对")
}
6
)
java
提供了
throws
关键字来声明异常。可以使用方法定义声明异常。它向调用者函
数提供了此方法可能引发此异常的信息。它有助于调用函数处理并将该代码包含在
try-catch
块中,以避免程序异常终止。在
Scala
中,可以使用
throws
注解来声明异常
def main(args: Array[String]): Unit = {
f11()
}
@throws(classOf[NumberFormatException])
def f11()={
"abc".toInt
}
隐式转换
当编译器第一次编译失败的时候,会在当前的环境中查找能让代码编译通过的方法,用
于将类型进行转换,实现二次编译
可以扩展代码的功能。相当于设置了默认值。
隐式转换可以在不需改任何代码的情况下,扩展某个类的功能
隐式函数
class MyRichInt(val self: Int) {
def myMax(i: Int): Int = {
if (self < i) i else self
}
def myMin(i: Int): Int = {
if (self < i) self else i
}
}
object TestImplicitFunction {
// 使用 implicit 关键字声明的函数称之为隐式函数
implicit def convert(arg: Int): MyRichInt = {
new MyRichInt(arg)
}
def main(args: Array[String]): Unit = {
// 当想调用对象功能时,如果编译错误,那么编译器会尝试在当前作用域范
围内查找能调用对应功能的转换规则,这个调用过程是由编译器完成的,所以称之为隐
式转换。也称之为自动转换
println(2.myMax(6))
}
}
隐式参数
普通方法或者函数中的参数可以通过
implicit
关键字声明为隐式参数,调用该方法时,
就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值。
(
1
)同一个作用域中,相同类型的隐式值只能有一个
(
2
)编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。
(
3
)隐式参数优先于默认参数
object TestImplicitParameter {
implicit val str: String = "hello world!"
def hello(implicit arg: String="good bey world!"): Unit = {
println(arg)
}
def main(args: Array[String]): Unit = {
hello
}
}
隐式类
在
Scala2.10
后提供了隐式类,可以使用
implicit
声明类,隐式类的非常强大,同样可
以扩展类的功能,在集合中隐式类会发挥重要的作用。
(
1
)其所带的构造参数有且只能有一个
(
2
)隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是
顶
级的
object TestImplicitClass {
implicit class MyRichInt(arg: Int) {
def myMax(i: Int): Int = {
if (arg < i) i else arg
}
def myMin(i: Int) = {
if (arg < i) arg else i
}
}
def main(args: Array[String]): Unit = {
println(1.myMax(3))
}
}
隐式解析机制
(
1
)首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。
(一
般是这种情况)
(
2
)如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。
类型的作用域是指与
该类型相关联的全部伴生对象
以及
该类型所在包的包对象
。
package com.atguigu.chapter10
import com.atguigu.chapter10.Scala05_Transform4.Teacher
//(2)如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。
类型的作用域是指与该类型相关联的全部伴生模块,
object TestTransform extends PersonTrait {
def main(args: Array[String]): Unit = {
//(1)首先会在当前代码作用域下查找隐式实体
val teacher = new Teacher()
teacher.eat()
teacher.say()
}
class Teacher {
def eat(): Unit = {
println("eat...")
}
}
}
trait PersonTrait {
}
object PersonTrait {
// 隐式类 : 类型 1 => 类型 2
implicit class Person5(user:Teacher) {
def say(): Unit = {
println("say...")
}
}
}
泛型
1
)语法
class MyList[
+T
]{ //
协变 }
class MyList[
-T
]{ //
逆变 }
class MyList[
T
] //
不变
协变:
Son
是
Father
的
子类
,则
MyList[Son]
也作为
MyList[Father]
的
“子类”
。
逆变:
Son
是
Father
的
子类
,则
MyList[Son]
作为
MyList[Father]
的
“父类”
。
不变:
Son
是
Father
的
子类
,则
MyList[Father]
与
MyList[Son]
“无父子关系”
。
//泛型模板
//class MyList<T>{}
//不变
//class MyList[T]{}
//协变
//class MyList[+T]{}
//逆变
//class MyList[-T]{}
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}
object Scala_TestGeneric {
def main(args: Array[String]): Unit = {
//var s:MyList[Child] = new MyList[SubChild]
}
}
泛型上下限
Class PersonList[
T <: Person]
{ //
泛型上限 }
Class PersonList[
T >: Person
]{ //
泛型下限 }
class Parent{}
class Child extends Parent{}
class SubChild extends Child{}
object Scala_TestGeneric {
def main(args: Array[String]): Unit = {
//test(classOf[SubChild])
//test[Child](new SubChild)
}
//泛型通配符之上限
//def test[A <: Child](a:Class[A]): Unit ={
// println(a)
//}
//泛型通配符之下限
//def test[A >: Child](a:Class[A]): Unit ={
// println(a)
//}
//泛型通配符之下限 形式扩展
def test[A >: Child](a:A): Unit ={
println(a.getClass.getName)
}
}
上下文限定
def f[A : B](a: A) = println(a) //等同于 def f[A](a:A)(implicit arg:B[A])=println(a)
上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定
[A :
Ordering]
之后,方法内无法使用隐式参数名调用隐式参数,需要通过
implicitly[Ordering[A]]
获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误
def f[A:Ordering](a:A,b:A) =implicitly[Ordering[A]].compare(a,b)
def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)
来源:
尚硅谷