Chapter 5: Scala Types Hierarchy

We know Scala is a pure OO language. So like Java, Scala contains huge predefine types of hierarchy like Java, as below:

In Scala, there are no primitive types. All basic types are also classes and they are part of the class hierarchy. Scala type hierarchy divided into two categories which are AnyRef and AnyVal.

AnyVal (which is called value types) hierarchy denoted to those classes which are similar to primitive types in Java like int, float, double and more. If you are creating your own value types, after compilation, they managed as a primitive type.

AnyRef (which equals to java.lang.Object) all non-value type classes or user-defined classes are the part of AnyRef in Scala hierarchy. After compilation, all these classes are extended from java.lang.Object and use similarly to Java classes.

Scala contains bottom types which defined the least subclass in the type hierarchy. These subclasses are Nothing and Null. The important feature of these classes is, we are not able to create direct instance of these classes. Instances of these classes managed by compiler under the hood with some tricks. Let's start with these classes.

Null: Null is a final abstract class in Scala library. Instance creation of Null classes is possible via the null keyword in scala like below:

val result : AnyRef = null

With the help of nullkeyword, we can create the instance. But Null is a bottom class of AnyRef hierarchy only. If we are trying to assign null to Int type, we are getting an error.

val intResult: Int = null
<console>:11: error: an expression of type Null is ineligible for implicit conversion
       val intResult: Int = null

The reason is, in the bytecode, all AnyVal types are treated as a primitive in Java and we know, within primitive types, null assignment is invalid, that’s why Scala defines Null is only a subclass of AnyRef hierarchy.

Nothing: Nothing is a final abstract class in scala library and it is a subclass of all types, which are AnyRef or AnyVal doesn’t matter. Instance creation of Nothing is not directly possible, this is what my fidings are. In scala for declaring Nothing type, we need to throw an exception as below:

def method: Nothing = throw new Exception

When we execute this method, it throws an exception and Nothing instance never been created. As per my experience, there is no way to create an instance of Nothing. Now the question is, why do we require Nothing?

We know, Scala supports both Functional and OOPs paradigms. In FP everything is evaluated as an expression, that's why in Scala we don’t have any statement, everything is an expression, even do-while, while, if and more. In Java throw is treated as a statement, but in Scala, everything is an expression and we can use throw exception in anywhere of break our flow like below example:

val result : User = Obj match {
	case value: Manager => value
	case value: Admin => value
	case _ => throw new Exception
}

In an example, we are breaking our flow with throw exception. But we are expecting, if we have an object of Manager or Admin we want to return the value of User type. If throw return Unit as per other expressions like while and do-while, in that case, our result would be the type of Any because Unit is a sub-type of AnyVal hierarch and in that case, our most common type is Any. So, that’s why Scala plays a trick here and throw expression return the least subclass from hierarchy because in that case, our common type would be decided on the basis of other expressions like in pattern matching it decided on the basis of Manager and Admin hierarchy common type which is called User.

Last updated