隐式参数是级别在中间的一种参数形式。在调用是可以写也可以不写。在有隐式参数的方法中,调用此方法,那么JVM虚拟机首先寻找的是传参,再传参没有找到的情况下,才会去寻找隐式参数,如果不巧的是隐式参数也没有,这是JVM还会去寻找参数默认值,如果都没有,则调用时会报错,提示需要传参,要么就去写隐式参数。
用法如下: package Implicit object ImplicitDemo_value_parameter { def main(args: Array[String]): Unit = { //声明隐式值,注意同种类型只能声明一个值,否则运行错误(ambiguous--模糊的无法确定到底引用哪个值) implicit val x = 1 implicit val y = "hello implicit" //隐式参数必须使用函数柯里化,且在函数参数列表最后一项,只可有一个implicit关键字修饰 //隐式参数可有默认值,其优先级为:传指定参数>隐式值>默认值 def showMsg(a:Int,b:Int)(implicit x1:Int=2,y1:String="hello"):Int={println(y1);a+b+x1} //调用时不传参数,优先使用隐式值 println(showMsg(1, 2))//hello implicit 换行 4 //调用时传入参数,优先级最大 println(showMsg(1, 2)(7,"Hello Implicit"))//Hello Implicit 换行 10 } }又称隐式转换,用于类型不匹配时自动转换类型或关联两个类(即类型增强)。 和隐式参数差不多,只不多这里将隐式参数换成了隐式函数。隐式函数可以在自己创建了某个类对象就拥有相应的方法。隐式参数就是不需要new相应的类的对象,就可以拥有它的方法。
package Implicit class Person { def showMsg={println("我是一个人")} } class ImplicitDemo_function object ImplicitDemo_function { def main(args: Array[String]): Unit = { //val s:Int =1.5 这种声明如果不写隐式转换函数,会直接报错,如果定义了隐式转换函数就可以自动转换为Int //定义转换函数需要根据需求来写,比如上面的例子需要把Double类型转化为Int类型 implicit def double2int(x:Double):Int=x.toInt val s:Int = 1.5 //隐式转换函数也可使得两个毫无关系的类之间关联起来,也叫类型增强如下: implicit def demoToPerson(x:ImplicitDemo_function):Person=new Person val demo = new ImplicitDemo_function //因为使用了隐式函数关联,可直接使用Person类的方法,这样两个毫无关系的类就可关联起来了,可随心所欲的扩展 demo.showMsg//我是一个人 } }隐式类一般为实体类服务,可以隐式的为实体类增加方法。在实体类创建对象后自动获得此方法。相当于隐式类为目标类放开了权限,只要目标类创建了对象,该对象就可以调用隐式类中的方法。隐式类必须写在object类中,因为object类相当于java中的静态类,在代码执行前编译,这样才能被找到。一般来说隐式类写在一个包中最好,方便查找,包括隐式函数和隐式参数。
注意:隐式类只能声明在object中 举个例子详细说明隐式类的方法:使用jdbc连接mysql
等同于:
package nj.zb.kb09.implicitdemo object Impliciteg { implicit val num:Int=10 //定义隐式参数 implicit val msg:String="hello" } package nj.zb.kb09.implicitdemo object Demo1 { def main(args: Array[String]): Unit = { import nj.zb.kb09.implicitdemo.Impliciteg._ val result=sum(10,10) println(result) //30 showMsg("gree") //hello:gree } def sum(a:Int,b:Int)(implicit c:Int):Int= { a+b+c } def showMsg(name:String)(implicit hi:String):Unit={ println(hi+":"+name) } }等同于:
package nj.zb.kb09.implicitdemo object Impliciteg { implicit def doubleToInt(value:Double):Int=value.toInt implicit def stringToInt(value:String):Int=Integer.parseInt(value) } object Demo1 { def main(args: Array[String]): Unit = { import nj.zb.kb09.implicitdemo.Impliciteg._ val num:Int=3.5 println(num) val num2:String="1" println(num2) } }demo2:
package nj.zb.kb09.implicitdemo object Impliciteg2 { implicit class Demo2Implicit(deom2:Demo2){ def aa(s:String):Unit = println(s) def bb(num:Int):String={ if(num%2==0) "偶数" else "奇数" } def add(num1:Int,num2:Int):Int= num1+num2 } implicit class Demo2Implicit2(demo2:Demo2){ def login(name:String,pwd:String):Boolean={ if(name.equals("zs")&& pwd.equals("123")) true else false } } } package nj.zb.kb09.implicitdemo class Demo2 {} object Demo2{ def main(args: Array[String]): Unit = { import nj.zb.kb09.implicitdemo.Impliciteg2._ val demo2=new Demo2 demo2.aa("abc") //abc println(demo2.add(12, 12)) //24 println(demo2.bb(3)) //奇数 println(demo2.login("aa", "123")) //false } }