12 异常
- Scala中的异常不区分所谓的编译时异常和运行时异常
- 也无需显示抛出方法异常,所以Scala中没有throws关键字。
scala中异常的处理方式类似于模式匹配,如果异常类型没有匹配成功,也不会发生MatchError,只是将异常直接报给了JVM
12.1 java中的异常:
try {
int a = 10;
int b = 0;
int c = a / b;
} catch (ArithmeticException e){
// catch时,需要将范围小的写到前面
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
} finally {
System.out.println("finally");
}
12.2 scala中的异常
object ScalaException {
def main(args: Array[String]): Unit = {
try {
var n= 10 / 0
}catch {
case ex: ArithmeticException=>{
// 发生算术异常
println("发生算术异常")
}
case ex: Exception=>{
// 对异常处理
println("发生了异常1")
}
}finally {
println("finally")
}
}
}
12.3 Java中的finally和return
public class FinallyTest {
public static void main(String[] args) {
System.out.println(test()); // 结果为1
}
public static int test(){
int i = 0;
try {
return i++;
}finally {
return i++;
}
}
}
public class FinallyTest {
public static void main(String[] args) {
System.out.println(test()); //结果为0
}
public static int test(){
int i = 0;
try {
return i++;
}finally {
i++;
}
}
}
13 隐式转换
13.1 隐式转换简介
什么是隐式转换?
其实之前学的自动类型转换,精度小类型可以自动转换成精度大的类型,由编译器自动完成的操作,就叫做隐式转换。
Scala在程序编译错误时,可以通过隐式转换中类型转换机制,进行二次编译。
将本身无法编译通过的代码通过类型转换后编译通过。
在相同作用域内,如果有相同的转换规则,转换规则的名字不同也会出错。
13.2 隐式函数
什么是隐式函数?
使用implicit关键字修饰的函数,称为隐式函数,可以被编译器在编译时使用。
就比如说原来一个函数的参数是一个Int类型,现在想修改这个参数类型为Double,那么就可以使用隐式函数,在编译的时候去自动查找这个编译规则。
object TestTransform_review {
def main(args: Array[String]): Unit = {
// 2 implicit声明一个隐式函数,将Double => Int
implicit def intToDouble(age: Double) : Int = {
age.toInt
}
test(13)
// 1 当传入一个double类型的参数编译就无法通过~
// 3 这样传入一个double类型的参数,编译就能通过了~
//程序已经编译出现错误,编译器会尝试在指定范围内查找指定的转换规则
//Double => Int,自动应用这个规则,让错误的程序可以编译通过
//将这个操作称之为二次编译,这个转换是由编译器自动完成的,所以称为隐式转换
test(29.12)
}
def test(age : Int) ={
println(age)
}
}
实例操作
之前使用动态混入可以实现对功能的扩展。使用隐式函数也可以~
object TestTransform_review_1 {
def main(args: Array[String]): Unit = {
// //方式1 使用动态混入,添加新的功能
// val user = new User with updateUser
// user.insertUser()
// user.updateUser()
//方式2 使用隐式函数,添加新的功能
//定义一个隐式函数,将User转换成UserExt
implicit def transform(user: User) : UserExt = {
new UserExt()
}
val user = new User
user.insertUser()
user.updateUser()
//编译出现错误 -> 隐式转换规则
//所谓的隐式转换其实就是通过类型的转换实现编译操作
//如果在同一个作用域范围内,有相同类型的多个转换规则,那么会发生错误
}
//声明一个含有新功能的类。
class UserExt(){
def updateUser() = {
println("updateUser----")
}
}
// //声明一个trait特征,实现新的功能
// trait updateUser {
// def updateUser() = {
// println("updateUser....")
// }
// }
class User(){
def insertUser(): Unit ={
println("insertUser....")
}
}
}
13.3 隐式参数 & 隐式变量
什么是隐式参数?
隐式参数就是告诉编译器,这个参数有可能会改。
object TestTransform_review_2 {
def main(args: Array[String]): Unit = {
//1 定义一个regUser(),参数password含有默认值000000
//3 当知道这个参数有可能会改,可以使用隐式变量,implicit
def regUser(implicit password : String = "000000") = {
println(password)
}
//4 给隐式变量赋值
implicit var pwd = "666666"
regUser() //000000
//2 这个时候如果想修改密码,可以直接传入新的密码
regUser("123123") //123123
//5 隐式参数不需要传递参数,也不需要写参数列表
//如果使用小括号,那么隐式变量不起作用
regUser //666666
}
}
13.4 隐式类
在Scala2.10后提供了隐式类,可以使用implicit声明类,隐式类非常强大,同样可以扩展类的功能,在集合的数据处理中,隐式类发挥了重要的作用。
-
其所带的构造参数有且只能有一个
-
隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的。
object ScalaImplicit {
def main(args: Array[String]): Unit = {
val emp = new Emp()
emp.insertUser()
}
class Emp {
}
implicit class User( emp : Emp) {
def insertUser(): Unit = {
println("insert user...")
}
}
}
13.5 隐式机制
所谓的隐式机制,就是一旦出现编译错误时,编译器会从哪些地方查找对应的隐式转换规则
Ø 当前代码作用域
Ø 当前代码上级作用域
Ø 当前类所在的包对象
Ø 当前类(对象)的父类(父类)或特质(父特质)
其实最直接的方式就是直接导入。