From the API doc I found that Null is a trait, but it says its sole instance is null.
abstract final class Null extends AnyRef
Null is - together with scala.Nothing - at the bottom of the Scala type hierarchy.
Null is a subtype of all reference types; its only instance is the null reference. Since Null is not a subtype of value types, null is not a member of any such type. For instance, it is not possible to assign null to a variable of type scala.Int.
How is it possible to instantiate a trait? Any simple example to realize this concept would really helpful.
You cannot instantiate an instance of the class Null, as it is abstract and final. Null is a figment of the compiler similar Nothing, used as a bottom-type for all reference types. That is, Null is a sub-type of any other type that inherits from AnyRef. Its only value is the null reference, but there is no way to instantiate the Null class and magically get a null reference. It differs from Nothing in that it is inhabited by a single value: null.
Therefore, if you assign null to an identifier, Null will be inferred as its type if you don't hint otherwise.
scala> val a = null
a: Null = null
Related
I'm new in scala, and while trying to understand below code, found lot of doubts. Please help me to understand this
There is one scala file named as MyEnums.scala, and code present within it as follow
object AllEnums extends Enumeration {
type Enums = Value
val one,two,three = Value
def getAllValues() : String = values.mkString(",")
}
I'm new in scala, also bit confused same enumeration logic in Java too. Trying to understand how enum defined here.
Is AllEnums is a object of class MyEnums.scala ?
If 1 point is correct that means, MyEnums.scala extending class MyEnums.scala ?
type Enums = Value, Value is type in scala, what's a real significance of it and what this statement type Enums = Value is doing in code ?
val one,two,three = Value, In this statment Is = Value means the values assigned to val one,two,three are of type Value ?
val one,two,three, Are these instance variables of class MyEnums.scala, whic is nothing but of Enumeration Type ?
what's a type of these vals one,two,three ? Assigning values to these are of Value type, but is there any type of these variables itself one,two,three ?
Is AllEnums is a object of class MyEnums.scala ?
No
If 1 point is correct that means, MyEnums.scala extending class MyEnums.scala ?
No
type Enums = Value, Value is type in scala, what's a real significance of it and what this statement type Enums = Value is doing in code ?
type Enums = Value makes Enums an alias of Value.
As for "significance" of it, I am not sure how to answer that. What is the "real significance" of Boolean?
val one,two,three = Value, In this statment Is = Value means the values assigned to val one,two,three are of type Value ?
Yes
val one,two,three, Are these instance variables of class MyEnums.scala, whic is nothing but of Enumeration Type ?
MyEnums.scala is a file, not a class.
one, two, three are members of AllEnums, and it certainly is not "nothing".
what's a type of these vals one,two,three ?
It is Value as you said yourself above. Or Enums, which is the same as. Value.
Assigning values to these are of Value type, but is there any type of
these variables itself one,two,three ?
Yes. Value.
I am new to scala. Please help me to understand below code snippet
null.==("goutam") // ---> return false
null.equals("goutam") // ---> throw NullPointerException
As per my understanding null is the only instance of Null trait which extends Anyref and == and equals both are functions of AnyRef. so why first statement does not throw but second one does?
Why first statement does not throw but second one does
Per the language specification (6.3), there are specific methods on null which will not cause a NullReferenceException to occur if invoked. They're defined as:
6.3 The Null Value
The null value is of type scala.Null, and is thus
compatible with every reference type. It denotes a reference value
which refers to a special “null” object. This object implements
methods in class scala.AnyRef as follows:
eq(x) and ==(x) return true iff the argument x is also the "null"
object.
ne(x) and !=(x) return true iff the argument x is not also the
"null" object.
isInstanceOf[T] always returns false.
asInstanceOf[T] returns the default value of type T.
## returns 0.
A reference to any other member of the "null" object causes a NullPointerException to be thrown.
equals is defined on AnyRef and doesn't handle null values as per definition. eq, which checks for reference equality (that's usually not what you want to do) can be used:
scala> null.==("goutam")
res0: Boolean = false
scala> null.eq("goutam")
res1: Boolean = false
== does handle null properly, and that is what you should be using. More on that in Whats the difference between == and .equals in Scala?
Why doesn't this work?
trait testtrait[T] {
var ob:T = null
}
then scalac testtrait.scala produces
testtrait.scala:2: error: type mismatch;
found : Null(null)
required: T
var ob:T = null
^
one error found
I'm using Scala 2.9
I can't say why exactly, but underscore notion (which is shortcut for default value for type, which is null for objects) will work fine:
trait testtrait[T] {
var ob:T = _
}
More dreaded workaround is asInstanceOf cast, but I found underscore better alternative.
trait testtrait[T] {
var ob:T = null.asInstanceOf[T]
}
null is a value of type Null, but not any type has Null as a subtype, only AnyRef-derived ones (except Nothing, of course). Suppose that you did something like
object SomeObj extends testtrait[Int]
What SomeObj.ob should be equal to? It is an Int, so it does not have null as a possible value.
As it is said in other answers, you should use underscore syntax to set default value for the type.
The bottom type of all types is Nothing. That means any type T, not otherwise constrained, can be Nothing, and null is not a Nothing (in fact, no value is).
So, to be able to assign null, you'd have to write it [T >: Null] (T is a supertype of Null).
On the other hand, you can initialize it to the default value using var ob: T = _. However, be aware that for any AnyVal, T will be boxed and assigned null instead of, say, 0, which can lead to unexpected results.
According to the scala docs:
Null is a subtype of all reference types;
So in theory, in this example we can assume Null is a subtype of Foo (a reference type) and that we should be able to attempt to call the bar method on an instance of type Null. In practice we can't and the code snippet fails at compile time with the error value bar is not a member of Null.
case class Foo(bar: String)
val n: Null = null
n.bar
Try it
I think it makes sense that we catch this at compile time because as the scala docs also say [Null's] only instance is the null reference, however I think a better error message would be Calling bar on type Null can only result in a NullPointerException.
My question is regarding the following code snippet, which doesn't fail at compile time and instead fails at runtime with a NullPointerException
val n: Null = null
n.toString
Try it
I am assuming this is because the Null type doesn't truly subclass every other reference type and only subclasses AnyRef, but is there any reason why this shouldn't throw a compile time error (or at least warning) that this code can only result in a NullPointerException? Is it deliberate that calling null.bar and null.toString behave differently?
Null is a subtype of all reference types; - this means something like that:
val n: Foo = null
n.bar //throws NPE
val a: String = null
a.charAt(0) //NPE again
So you can say Null is a subtype of all reference types.
edit: The
val n: Null = null
n.bar
part is incorrect. According to Scala docs:
abstract final class Null extends AnyRef
AnyRef doesnt' have a bar. You cannot say like this, right?
val n: AnyRef = ""
n.charAt(0) //won't compile
I just read this question and stumbled upon the following quote:
Scala treats == as if it were defined as follows in class Any:
final def == (that: Any): Boolean =
if (null eq this) (null eq that) else (this equals that)
The (null eq this) part made me wonder: Is it actually possible to call methods on null pointers? Can this be null in Scala?
Check out the Scala language specification, namely 6.3 The Null Value chapter:
The null value is of type scala.Null, and is thus compatible with every reference
type. It denotes a reference value which refers to a special “null” object. This object
implements methods in class scala.AnyRef as follows:
• eq(x) and ==(x) return true if the argument x is also the “null” object.
• ne(x) and !=(x) return true if the argument x is not also the “null” object.
This means that semantically when you compare something with null literal or null literal with something you are actually referring to method of a special scala.Null class. Treat null literal as a shorthand for that class.
Of course at the implementation level it is optimized and ordinary null is used.
null is the only instance of Null class and it's a valid object. Null is a subtype of all reference types.
I'm pretty new to Scala, but the only way I see that as being possible is due to the fact that "null" itself is an instance of Null, and not exactly a special value like "null" in Java.
http://blog.sanaulla.info/2009/07/12/nothingness/
This article helped me understand this a bit better.