Scala 异常处理和隐式转换 (九)

异常

回顾下Java中的异常类型

|- Throwable
	|- Error  系统底层错误,无法处理
	|- Exception 应用异常,可以处理
		|- RuntimeException  运行时异常
		|- 非RuntimeException 检查时异常

scala 中的异常和Java中的一致,调用的都是Java的中异常类

package object scala extends scala.AnyRef {
  type Throwable = java.lang.Throwable
  type Exception = java.lang.Exception
  type Error = java.lang.Error
  type RuntimeException = java.lang.RuntimeException
  type NullPointerException = java.lang.NullPointerException
  type ClassCastException = java.lang.ClassCastException
  //..../
  }

常见的异常类型

  • NullPointerException 常见错误,不接受反驳
  • ClassCastException 类型转换异常
  • ArrayIndexOutOfBoundsException 下标越界异常
  • ClassCastException 类型转换异常

Scala中异常处理

消极处理

抛出异常

  • java语法:throw 异常.... throws 声明抛出异常
  • scala语法:throw 异常...
object Exception01 {
  def main(args: Array[String]): Unit = {
    f1()
  }

  def f1(): Unit ={
    println("start ...")

    // 手动抛出异常
    throw new java.lang.RuntimeException("程序错误...")

    println("end ...")
  }
}

积处理

语法:try ... catch .. finally

package exceptions

object Exception02 {
  def main(args: Array[String]): Unit = {
    try {
      // 积极处理
      println("start ....")
      var m: Int = 1 / 0
      println("end ....")
    } catch {
      // 模式匹配的语法 case 类型
      case e0: ArithmeticException => e0.printStackTrace()
      case e1: RuntimeException => println("runtime exception")
      case e2: Exception => println("exception ...")
      case _ => println("other ...")
    } finally {
      println("finally ...")
    }
  }
}

异常应用 scala jdbc

package execptions

import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}

import scala.collection.mutable.ArrayBuffer
import scala.util.Properties

/**
  * 连接JDBC
  * 	JDBC 五大步骤
  */
object JDBCTest extends App {

  var conn: Connection = null
  var statement: PreparedStatement = null
  var users: ArrayBuffer[User] = null
  var set: ResultSet = null

    try{
    Properties.setProp("scala.time", "true")

    Class.forName("com.mysql.jdbc.Driver")

    conn = DriverManager.getConnection("jdbc:mysql://localhost/test","root","1234")

    statement = conn.prepareStatement("select * from t_user")

    users = new ArrayBuffer[User]()

    set = statement.executeQuery()

    while (set.next()) {

      val user: User = new User

      val id = set.getInt("id")

      val name = set.getString("name")

      val sex = set.getBoolean("sex")

      user.id = id
      user.name = name
      user.sex = sex
      users += user
    }
  }

  if(set != null) set.close()
  if(statement != null) statement.close()
  if(conn != null) conn.close()

  users.foreach(println)

}
// -------------------------实体类------------------------

package execptions

class User {

  var id: Int = _

  var name: String =_

  var sex: Boolean = _

  override def toString = s"User($id, $name, $sex)"
}

隐式转换

隐式转换函数(implicit conversion function)指的是以implicit关键字声明的带有单个参数的函数。这样的函数将被自动应用,将值从一种类型转换为另一种类型。隐式转换函数叫什么名字是无所谓的,因为通常不会由用户手动调用,而是由Scala进行调用。但是如果要使用隐式转换,则需要对隐式转换函数进行导入(import)。因此通常建议将隐式转换函数的名称命名为“one2one”的形式。

常用使用方式:

  • 隐式值
  • 隐式参数
  • 隐式函数
  • 隐式增强
  • 隐式类

Scala会考虑如下位置的隐式转换函数:

  • 位于源或目标类型的伴生对象中的隐式函数
  • 位于当前作用域可以以单个标识符指代的隐式函数

隐式转换在如下三种不同情况下会被考虑:【知道】

  • 当表达式类型与预期类型不同时【隐式值的使用】
  • 当对象访问一个不存在成员时【隐式增强】
  • 当对象调用某个方法,而这个方法的参数声明与传入参数不匹配时【隐式函数】

有三种情况编译器不会尝试使用隐式转换: 【知道】

  • 如果代码能够在不使用隐式转换的前提下通过编译,则不会使用隐式转换
  • 编译器不会尝试同时执行多个转换
  • 存在二义性的转换是错误

隐式值

package implicits

object ImplicitValue01 extends App {

  implicit var name: String = "张三"
  implicit var age: Int = 18

  // 获取类型为String 的隐式值
  val zs = implicitly[String]
  println(zs)

  val zsage = implicitly[Int]
  println(zsage)
}

隐式参数

总结: 所谓隐式参数,指scala在编译不通过时,在当前类或者作用域中寻找隐式参数同类型的隐式值,赋予隐式参数,完成函数处理;

package implicits

/**
  * 隐式参数
  *   柯里化函数,当参数不匹配的时候会去作用域中寻找类型相同的隐式参数
  *   参数符合的时候就不会查找隐式参数
  */
object ImplicitValue02 extends App {


  implicit val num: Int = 10

  println(sum(5)) // 15

  println(sum(5)(20)) // 25

  def sum(x: Int)(implicit y: Int) = x + y

}

隐式函数

总结:所谓的隐式函数,指scala在编译不通过时,自动尝试将一个中类型转换为另外的一种类型;

package implicits

/**
  * 隐式函数
  *   编译时函数形参匹配不通过时,自动尝试将类型转为另一种类型
  */
object ImplicitValue03 extends App {

  val student = new Student

  student.run(1)

  // 需要指定返回值类型 返回值类型只有在编译时候才会被推断
  // 要指定返回值类型使隐式函数自动根据类型调用
  implicit def intToString(num: Int): String={
    num + ""
  }

  // 同类型只能有一个
  /*implicit def intToString1(num: Int): String={
    num + ""
  }*/

}

class Student{

  def run(name: String): Unit ={
    printf("%s 在跑 \n",name)
  }

}

隐式增强

通过隐式转换增强某一个类的功能

package implicits
/**
 * 增强man,使man具有fly方法
 */
object ImplicitValue04 extends App {

  private val man = new Man

  man.fly

  // 传递一个man 返回一个supperMan对象
  implicit def manToSupperMan(man: Man): SupperMan ={
    new SupperMan
  }
}

class Man

class SupperMan{

  def fly(): Unit ={
    println("supperMan fly...")
  }

}

隐式类

implicit修饰的特殊类,注意不能独立声明,需要定义在一个类\对象的内部

package implicits

/**
  * 隐式类
  * 	对类进行增强
  */
object ImplicitValue05 {

  def main(args: Array[String]): Unit = {
    val man = new Man2("lisi")

    man.fly
  }

  implicit class Boss(man: Man2){
    var name: String = _

    this.name = man.name

    def fly() = println(name + "   fly ...")
  }
  class Man2(var name:String)
}

隐式转换的导入

如何使用当前类以外的隐式转换呢?

导入外部类中的隐式值
package implicits

/**
  * 获取 外部类中的隐式值
  */
object ImplicitValue06 extends App {
	// 类需要new 创建对象
  val aa = new A

  import aa._

  private val i: Int = implicitly[Int]

  println(i)
  class A{
    implicit def num: Int = 5
  }

}
导入外部对象中的隐式方法
package implicits

/**
  * 获取外部对象的隐式值
  */
object ImplicitValue07 extends App {

  import  Bb._

  run(1)

  def run(name :String)={
    println(name + " is running...")
  }
}

object Bb{
  implicit def intToString(num: Int):String={
    num + "lisi"
  }

  // 隐式方法重载
  implicit def intToString(num: Double):String={
    num + "lisi"
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值