2016-12-16 1 views
2

Scala версии 2.12.1-20161205-201300-2787b47Вызов `ConcurrentLinkedQueue.poll` на пустой очереди, кажется, возвращает 0, вместо нулевой

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

Вы не можете назначить 'null' для' Int' (это не ссылочный тип). Таким образом, он преобразует его в 0. Использование null не рекомендуется в scala вообще. Это одна из причин этого. Вы пишете Java-код в синтаксисе scala, это не очень полезно. Входите в менталитет scala. – Dima

+0

@Dima Есть ли какая-либо альтернатива scala для ConcurrentLinkedQueue? – jilen

ответ

1

В Скала, Int распространяется AnyVal. Типы, которые расширяются AnyVal, не могут привязываться к значению null.

Этот код соответствует тому, что существует бокс и unboxing, происходящий за крышками между 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. Будьте внимательны при выполнении такого взаимодействия между Java-классами в Scala.

Смежные вопросы