【问题标题】:ConcurrentMap#putIfAbsent with Scala Int'sConcurrentMap#putIfAbsent 与 Scala Int's
【发布时间】:2023-03-30 09:41:01
【问题描述】:

java.util.concurrent.ConcurrentMapputIfAbsent 文档对返回类型进行了如下说明:

与指定键关联的前一个值,如果该键没有映射,则为 null。

在 Scala 2.10.4 上,我尝试调用 putIfAbsent(Int, Int),即使用 Scala 的 Int 类型。

scala> import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap

scala> new ConcurrentHashMap[Int, Int]()
res0: java.util.concurrent.ConcurrentHashMap[Int,Int] = {}

scala> val x: Int = 1
x: Int = 1

由于1 不存在于空的ConcurrentHashMap 中,我希望nullputIfAbsent(x, x) 调用中返回。

scala> res0.putIfAbsent(x, x)
res1: Int = 0

但是,0 被返回。我假设null 被转换为0

这里到底发生了什么?它正在编译对我来说似乎很奇怪。

【问题讨论】:

    标签: scala concurrenthashmap


    【解决方案1】:

    Int 不能是null,也不能是任何AnyVal。来自scaladoc

    Null 是所有引用类型的子类型;它的唯一实例是空引用。由于 Null 不是值类型的子类型,因此 null 不是任何此类类型的成员。例如,不能将 null 分配给 scala.Int 类型的变量。

    如果我们直接尝试,会报错:

    scala> val i: AnyVal = null
    <console>:9: error: type mismatch;
     found   : Null(null)
     required: AnyVal
    Note that implicit conversions are not applicable because they are ambiguous:
     both method RichException in object Predef of type (self: Throwable)RichException
     and method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
     are possible conversion functions from Null(null) to AnyVal
           val i: AnyVal = null
    

    编译器用Int 的默认值填充它,即0

    例如:

    scala> def getNull[A](i: A): A = null.asInstanceOf[A]
    getNull: [A](i: A)A
    
    scala> getNull(1)
    res6: Int = 0
    

    在幕后,我们实际上无法将null 转换为Int,但可以将其转换为盒装类型。但是,一旦我们在应该类似于它所包含的原始类型的上下文中使用装箱类型,它就会转换为需要默认值的那种类型。

    【讨论】:

    • 感谢您的详细回答。您解释了 Scala Int 不能是 null。给定 Scala 方法:def f(x: Int): java.lang.Integer 和 Java 方法 public static int gf( g )永远返回 null
    • java.lang.Integer是一个类,所以可以是null
    • 是的,确实如此。抱歉耽搁了。感谢您对我所有问题的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多