在空队列上调用`ConcurrentLinkedQueue.poll`似乎返回0而不是null

时间:2016-12-16 11:03:14

标签: scala

Scala版本2.12.1-20161205-201300-2787b47

val max = 20
val queue = new java.util.concurrent.ConcurrentLinkedQueue[Int]()
(1 to 10).foreach(queue.offer)
def show(c: Int): Unit = {
    val e = queue.poll()
    if(c < max && e != null) {
      println(e)
      show(c + 1)
    }
  }
show(0)

Repl输出

1
2
3
4
5
6
7
8
9
10
0
0
0
0
0
0
0
0
0
0

发生了什么事?

1 个答案:

答案 0 :(得分:1)

在Scala中,Int扩展了AnyVal。扩展AnyVal的类型无法绑定到null值。

此代码符合,因为在IntInteger引用类型之间的封面后面发生了装箱和取消装箱。例如,要将ConcurrentLinkedQueue设置为Integer而不是Int

def apply$mcZI$sp(x$1: Int): Boolean = queue.offer(scala.Int.box(x$1));

当你通过offer提取一个值时,编译器会这样做:

val e: Int = unbox(queue.poll());

unbox转到BoxesRunTime.unboxtoInt

public static int unboxToInt(Object i) {
    return i == null ? 0 : ((java.lang.Integer)i).intValue();
}

这就是为什么你看到0而不是null的原因。在Scala中的Java类之间进行这种互操作时要小心。