Java Scala的隐式转换详解

 更新时间:2023年04月21日 09:56:04   作者:Java运动猿  
隐式转换是在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。本文通过代码示例介绍了Scala的隐式转换,感兴趣的小伙伴可以参考阅读

隐式转换是在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。

一、隐式值与隐式参数

隐式值是指在定义参数时前面加上implicit。隐式参数是指在定义方法时,方法中的部分参数是由implicit修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式转换作用就是:当调用方法时,不必手动传入方法中的隐式参数,Scala会自动在作用域范围内寻找隐式值自动传入。

隐式值和隐式参数需要注意以下几点:
1.同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。

2.implicit关键字必须放在隐式参数定义的开头

3.一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,调用时直接创建类型不传入参数即可。

4.一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次

package com.bjsxt.scala
 
 
object ImplicitValue {
  /**
   * 隐式值和隐式参数需要注意以下几点:
   * 1.同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。
   * 2.implicit关键字必须放在隐式参数定义的开头
   * 3.一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,调用时直接创建类型不传入参数即可。
   * 4.一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次
   */
 
    //   * 4.一个方法如果有多个参数,要实现部分参数的隐式转换,
    //   必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次
  def Student(age:Int)(implicit name:String,i:Int) = {
    println(s"student = $name,age = $age,score = $i")
  }
  
  //   * 3.一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,
  //   调用时直接创建类型不传入参数即可。
  def Teacher(implicit name:String) = {
    println(s"teacher name is =$name")
  }
  def main(args: Array[String]): Unit = {
    //   * 1.同类型的参数的隐式值只能在作用域内出现一次,
    //   同一个作用域内不能定义多个类型一样的隐式值。比如这里的String、Int类型,各自只能定义一个
    implicit val name:String = "zhangsan"
    implicit val i:Int = 100
 
    //这里使用了隐式参数,只用传入age那个参数,后面两个参数可以不填,默认使用隐式值
    Student(100)
    //这里是直接使用了隐式值,可以不填参数,当然也可以给定参数,给定参数的话就是取给的参数的值
    Teacher
  }
}

输出的结果:会自动寻找对应的函数,并且进行隐式转换。

student = zhangsan,age = 100,score = 100
teacher name is =zhangsan

二、隐式转换函数

隐式转换函数是使用关键字implicit修饰的方法。当Scala运行时,假设如果A类型变量调用了method()这个方法,发现A类型的变量没有method()方法,而B类型有此method()方法,会在作用域中寻找有没有隐式转换函数将A类型转换成B类型,如果有隐式转换函数,那么A类型就可以调用method()这个方法。

隐式转换函数注意:隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关,所以作用域内不能有相同的参数类型和返回类型的不同名称隐式转换函数。

package com.bjsxt.scala
 
class Animal(name:String){
  def canFly()= {
    println(s"$name can fly....")
  }
}
 
class Rabbit(xname:String){
  val name = xname
}
 
object ImplicitValue2 {
  
  //定义隐式转换函数
  implicit def RabbitToAnimal(r:Rabbit):Animal = {
    new Animal(r.name)
  }
  //注意隐式转换函数只与参数类型和返回值类型有关,
  // 与函数名无关,所以不能定义两个相同类型的函数,虽然函数名不同,下面这个就是非法的
//  implicit def Rabbit(r:Rabbit):Animal = {
//    new Animal(r.name)
//  }
 
  def main(args: Array[String]): Unit = {
    val rabbit = new Rabbit("rabbit")
    //这里rabbit调用不了canFly,因为Rabbit类中没有canFly方法,
    // 但定义了隐式转换函数,那就会往Animal类中找
    rabbit.canFly()
  }
}

运行结果:

rabbit can fly....

三、隐式类

使用implicit关键字修饰的类就是隐式类。若一个变量A没有某些方法或者某些变量时,而这个变量A可以调用某些方法或者某些变量时,可以定义一个隐式类,隐式类中定义这些方法或者变量,隐式类中传入A即可。

隐式类注意:

1.隐式类必须定义在类,包对象,伴生对象中

2.隐式类的构造必须只有一个参数,同一个类,包对象,伴生对象中不能出现同类型构造的隐式类。

package com.bjsxt.scala
//隐式类
 
class Rabbit1(xname:String){
  val name = xname
}
 
object ImplicitValue3 {
 
  //定义隐式类,只能在object中定义,并且只能传入一个参数
  //不能出现同类型构造的隐式类。(同类型:参数类型和返回值类型,与类名无关)
  implicit class Animal1(r:Rabbit1){
    def showName() = {
      println(s"${r.name} is Rabbit....")//对象.属性需要加“{}”
    }
  }
 
  def main(args: Array[String]): Unit = {
    val rabbit = new Rabbit1("RABBIT")
//    Rabbit1类中没有showName方法,这是会找隐式类
    rabbit.showName()
  }
 
}

运行结果:

RABBIT is Rabbit....

到此这篇关于Java Scala的隐式转换详解的文章就介绍到这了,更多相关Scala隐式转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈java中null是什么,以及使用中要注意的事项

    浅谈java中null是什么,以及使用中要注意的事项

    下面小编就为大家带来一篇浅谈java中null是什么,以及使用中要注意的事项。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 在IDEA中实现生成Maven依赖关系图

    在IDEA中实现生成Maven依赖关系图

    这篇文章主要介绍了在IDEA中实现生成Maven依赖关系图方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • springboot后端解决跨域问题

    springboot后端解决跨域问题

    今天小编就为大家分享一篇关于springboot后端解决跨域问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • java 获取服务器真实IP的实例

    java 获取服务器真实IP的实例

    这篇文章主要介绍了java 获取服务器真实IP的实例的相关资料,这里提供实现方法帮助大家学习理解这部分内容,需要的朋友可以参考下
    2017-08-08
  • IntelliJ IDEA 2021.3永久最新激活至2099年(亲测有效)

    IntelliJ IDEA 2021.3永久最新激活至2099年(亲测有效)

    最新版idea2021.3已出来,很多网友迫不及待的要升级idea2021最新版,今天小编抽空给大家整理了一篇教程关于idea2021.3最新激活教程,本文以idea2021.2.3为例通过图文并茂的形式给大家分享激活详细过程,感兴趣的朋友参考下吧
    2020-12-12
  • idea不能搜索任何插件的问题解决

    idea不能搜索任何插件的问题解决

    本文主要介绍了idea不能搜索任何插件的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Spring中的SpringApplicationRunListener详细解析

    Spring中的SpringApplicationRunListener详细解析

    这篇文章主要介绍了Spring中的SpringApplicationRunListener详细解析,SpringApplicationRunListener是一个监听SpringApplication中run方法的接口,在项目启动过程的各个阶段进行事件的发布,需要的朋友可以参考下
    2023-11-11
  • Java数据结构(线性表)详解

    Java数据结构(线性表)详解

    本文主要介绍了Java数据结构(线性表)的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • springboot单文件下载和多文件压缩zip下载的实现

    springboot单文件下载和多文件压缩zip下载的实现

    这篇文章主要介绍了springboot单文件下载和多文件压缩zip下载的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • SpringBoot集成H2内存数据库的方法

    SpringBoot集成H2内存数据库的方法

    H2是Thomas Mueller提供的一个开源的、纯java实现的关系数据库。本文主要介绍了SpringBoot集成H2内存数据库,具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09

最新评论