Reputation: 41909
I attempted to write a function that won't compile if null
is passed:
$scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101).
Type in expressions for evaluation. Or try :help.
scala> :t null
Null
scala> def f[A >: Null](x: A):A = x
f: [A >: Null](x: A)A
However, it did not work as I expected:
scala> f( null )
res1: Null = null
Upvotes: 6
Views: 151
Reputation: 149548
Scala specification section 3.5.2 (conformance) states (emphasis mine):
The
<:
relation forms pre-order between types, i.e. it is transitive and reflexive. least upper bounds and greatest lower bounds of a set of types are understood to be relative to that order.
So if we look at the type constructor declaration from a mathematical point of view, we see the :<
relation as:
Null <: T <: Any
Since by definition the relation is reflexive, Null <: Null
is in the relation, which makes null a valid value to be passed into the method.
As @sepp2k rightly said in the comments and in his answer, the fact that A
isn't constrained by an upper bound means that Any
is a valid candidate, which means a null value could be passed anyway.
Upvotes: 1
Reputation: 370212
As has been pointed out, A >: Null
allows for A
to be Null
itself, but that doesn't even matter here. Even if A
were required to be a strict supertype of Null
, it would still be possible to pass null
to f
as null
is a valid value of those types (which follows directly from the fact that Null
is a subtype of them).
If you don't want to accept nullable types, A
needs to be a subtype of AnyVal
. Note that this will prevent any values of reference types to be passed - not just null
itself.
There is no way to accept reference types without also accepting null.
Upvotes: 6
Reputation: 3126
A :> B
means that A
is a super-type of B
.
A >: Null
this bound means that A
is a super-type of Null
.
Null
has two super-types Any
and AnyRef
.
In Scala you can use Option
as a good mechanism to avoid null
usage.
What do you think about this?
Upvotes: -1