执行程序,scala抛出了异常,但是没有打印出来"hello world",说明程序出错后就终止执行了,scala中可以使用异常处理来解决这个问题
语法:
try { // 代码 } catch { case ex:异常类型1 => // 代码 case ex:异常类型2 => // 代码 } finally { // 代码 } try中的代码是我们编写的业务逻辑代码在catch中表示当出现某个异常时,需要执行的代码在finally中,是不管是出现异常都会执行的代码示例
示例说明
使用try…catch来捕获除零异常参考代码
package scala.demo object Demo18 { def main(args: Array[String]): Unit = { try { val i = 10 / 0 println("hello world") } catch { case ex:Exception =>println(ex.getMessage) } } }我们也可以在一个方法中,抛出异常,语法和Java类似,使用 throw new Exception…抛出异常
示例说明
在main方法中抛出一个异常参考代码
package scala.demo object Demo18 { def main(args: Array[String]): Unit = { throw new Exception("这是一个异常") } } Exception in thread "main" java.lang.Exception: 这是一个异常 at scala.demo.Demo18$.main(Demo18.scala:5) at scala.demo.Demo18.main(Demo18.scala) scala不需要在方法上声明要抛出的异常,它已经解决了在Java中被认为是设计失败的检查异常Java代码
public static void main(String[] args) throws Exception { throw new Exception("这是一个异常"); }要实现一个类的伴生对象中的apply()方法,可以通过类名来快速构建一个对象,伴生对象中,还有一个unapply的方法,和apply相反,unapply是将该类的对象,拆解为一个个的元素
要实现一个类的提取器,只需要在该类的伴生对象类中实现一个unapply的方法就行
语法:
def unapply(stu:Student):Option[(类型1, 类型2, 类型3...)] = { if(stu != null) { Some((变量1, 变量2, 变量3...)) } else { None } }示例
示例说明
创建一个Student类,包含姓名年龄两个字段实现一个类的解构器,并使用match表达式进行模式匹配,提取类中的字段。参考代码
package scala.demo object Demo18 { class Student(var name:String,var age:Int) object Student{ def apply(name:String,age:Int)=(new Student(name,age)) def unapply(student: Student)={val tuple=(student.name,student.age) Some(tuple) } } def main(args: Array[String]): Unit = { val student = Student("张三",20) student match{ case Student(name,age)=>println(s"${name}=>${age}") } } }scala和Java一样,类和特质,方法都支持泛型
scala> val list1:List[String] = List("1", "2", "3") list1: List[String] = List(1, 2, 3)在scala中,使用方括号来定义类型参数
语法:
def 方法名[泛型名称](..) = { //... }示例
示例说明
用一个方法来获取任意类型数组的中间的元素 不考虑泛型直接实现(基于Array[Int]实现)加入泛型支持参考代码
不考虑泛型的实现
package scala.demo object Demo19 { def getMiddle(arr:Array[Int])=arr(arr.length/2) def main(args: Array[String]): Unit = { val arr1 = Array(1,2,3) println(getMiddle(arr1)) } }加入泛型支持
package scala.demo object Demo19 { def getMiddle[T](arr:Array[T])=arr(arr.length/2) def main(args: Array[String]): Unit = { println(getMiddle(Array(1,2,3,4,5,6))) println(getMiddle(Array("a","b","c","d","e"))) } }scala的类也可以定义泛型
语法:
class 类[T](val 变量名: T) 定义的一个泛型类型,直接在类名后面加上方括号,指定要使用的泛型参数指定类对应的泛型参数后,就使用这些类型参数来定义变量示例
示例说明
实现一个Pair泛型类Pair类包含两个字段,而且两个字段的类型不固定创建不同类型泛型类对象,并打印参考代码
package scala.demo object Demo20 { case class Pair[T](var a:T,b:T) def main(args: Array[String]): Unit = { val pariList=List(Pair("hadoop","Storm"),("hadoop",2008),(1.0,2.0),("hadoop",Some(1.9))) println(pariList) } }需求: 我们在定义方法/类的泛型时,限定必须从哪个类继承,或者是哪个类的父类,此时就需要使用上下界
使用 <: 类型名 表示给类型名添加一个上界,表示泛型参数必须要从该类(或本身)继承
语法格式
[T <: 类型]示例
示例说明
定义一个Person类定义一个Student类,继承Person类定义一个demo泛型方法,该方法接收一个Array参数,限定demo方法的Array元素类型只能是Person或者Person的子类测试调用demo,传入不同元素类型的Array package scala.demo object Demo21 { class Person class Student extends Person def demo[T<:Person](a:Array[T])=println(a) def main(args: Array[String]): Unit = { demo(Array(new Person)) demo(Array(new Student)) //编译出错,必须是person的子类 // demo(Array("hadoop")) } }上界是要求必须是某个类的子类,或者必须从某个类继承,而下界这是必须是某个类的父类(或者本身)
语法:
[T >: 类型]注意:如果类既有上界,又有下界,那么下界写在前面,上界写后面
示例
示例说明
定义一个Person类定义一个Policeman类,继承Person类定义一个Superman类,继承Policeman类定义一个demo泛型方法,该方法接收一个Array参数,限定demo方法的Array元素类型只能是Person、Policeman测试调用demo,传入不同元素类型的Array参考代码
package scala.demo object Demo22 { class Person class Policeman extends Person class Superman extends Policeman def demo[T>:Policeman](array:Array[T])=println(array) def main(args: Array[String]): Unit = { demo(Array(new Person)) demo(Array(new Policeman)) //运行出错,Superman是Policeman的子类 // demo(Array(new Superman)) } }语法:
class Pair[T]{} 默认泛型类是非变的类型B是A的子类型,Pair[A]和Pair[B]没有任何从属关系JAVA是一样的语法格式
class Pair[+T] 类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型参数化类型的方向和类型的方向是一致的语法格式
class Pair[-T] 参数B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型参数化类型的方向和类型的方向是相反的示例
示例说明
定义一个Super类、以及一个Sub类继承自Super类使用协变、逆变、非变分别定义三个泛型类分别创建泛型类来演示协变、逆变、非变 package scala.demo object Demo23 { class Super class Sub extends Super class Temp1[T] class Temp2[+T] class Temp3[-T] def main(args: Array[String]): Unit = { val a: Temp1[Sub] = new Temp1[Sub] //编译报错:非变 // val b:Temp1[Super]=a //协变 val c:Temp2[Sub]=new Temp2[Sub] val d:Temp2[Super]=c //逆变 val e:Temp3[Super]=new Temp3[Super] val f:Temp3[Sub]=e } }