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
发生了什么事?
答案 0 :(得分:1)
在Scala中,Int
扩展了AnyVal
。扩展AnyVal
的类型无法绑定到null
值。
此代码符合,因为在Int
和Integer
引用类型之间的封面后面发生了装箱和取消装箱。例如,要将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类之间进行这种互操作时要小心。