What AnyRefs are not nullable?

25 views
Skip to first unread message

Haoyi Li

unread,
Jan 24, 2014, 3:03:12 AM1/24/14
to scala-user
This:

abstract class Reference[T <: AnyRef](var referent: T){
  def get: T = referent
  def clear: Unit = referent = null
}

Fails with

[error]  type mismatch;
[error]  found   : Null(null)
[error]  required: T
[error]   def clear: Unit = referent = null

This works though:

abstract class Reference[T >: Null <: AnyRef](var referent: T){
  def get: T = referent
  def clear: Unit = referent = null
}

Can someone explain what's going on here? If I have already bound T to be an AnyRef, how could it be non-nullable? Furthermore, why must I bound T to AnyRef in the first place? Aren't generics erased unless i @specialize them? 

Source: I'm trying to translate this code to ScalaJS from Java, where everything works fine without any weird type bound trickery.

Som Snytt

unread,
Jan 24, 2014, 3:38:28 AM1/24/14
to Haoyi Li, scala-user
Nothing is not Null, and AnyVal is not AnyRef.

Is that the question? Kind of late here.

Maybe you're thinking everything is boxed. But that's under the hood, or under the carpet.




--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jason Zaugg

unread,
Jan 24, 2014, 3:39:28 AM1/24/14
to Haoyi Li, scala-user
On Fri, Jan 24, 2014 at 9:03 AM, Haoyi Li <haoy...@gmail.com> wrote:
Can someone explain what's going on here? If I have already bound T to be an AnyRef, how could it be non-nullable? Furthermore, why must I bound T to AnyRef in the first place? Aren't generics erased unless i @specialize them? 

Source: I'm trying to translate this code to ScalaJS from Java, where everything works fine without any weird type bound trickery.

If A is an abstract type, `expr : A` will only typecheck if `expr` conforms to the lower bound of `A`. The default lower bound is `Nothing`. `Null` is not a subtype of `Nothing`.

If we allowed that:

scala> def foo[A <: AnyRef]: A = null.asInstanceOf[A]
foo: [A <: AnyRef]=> A

scala> {foo[Nothing]; ()}

-jason

martin odersky

unread,
Jan 24, 2014, 3:40:30 AM1/24/14
to Haoyi Li, scala-user
Only classes and traits that extend AnyRef are considered nullable. Abstract types and type parameters are not; they need an explicit >: Null bound. 

That's so that we can at some point introduce non-null types which might still inherit from AnyRef. 

Hope this helps

 - Martin


On Fri, Jan 24, 2014 at 9:03 AM, Haoyi Li <haoy...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Prof. Martin Odersky
LAMP/IC, EPFL
Station 14, 1015 Lausanne, Switzerland
Tel: +41 21 693 6863

Haoyi Li

unread,
Jan 24, 2014, 3:52:34 AM1/24/14
to martin odersky, scala-user
That's so that we can at some point introduce non-null types which might still inherit from AnyRef. 

Ok, that makes sense. Thanks =)
Reply all
Reply to author
Forward
0 new messages