Back2Basics: Type Erasure in Scala

Table of contents
Reading Time: 3 minutes

Scala has a really strong type system. Scala’s static type system is listed as one of its strong points.

But even though Scala’s type system is theoretically very strong, in practice some type-related features are weakened by the restrictions and limitations of its runtime environment, i.e. Type Erasure.

So, what is type erasure?

Type erasure refers to the runtime encoding of parameterized classes in Scala. It is simply performed by Scala compiler in which it removes all the generic type information after compilation.

In Scala, generics are erased at runtime, which means that the runtime type of List[Int] and List[Boolean] is actually the same. 

Now the question arises is why the compiler does so?

It is so because Scala was defined with Type Erasure as the Java Virtual Machine (JVM) did not get generics. Java didn’t support generics from the beginning. So keeping backward compatibility in mind, Type Erasure was defined in Java SE version 5.0 to allow seamless interfacing with old, non-generic legacy code.

What happens under the hood is that type parameter in a generic class are replaced either with Object or its upper bound. This means that, at runtime, only the class exists, not its type parameters.

In the example, JVM knows it is handling a, scala.collection.immutable.List but not that this list is parameterized with which dataType. The above code snippet compile successfully, but when you run it, it will give the following warning:

The reason for the warning is that the runtime has no idea about the actual class that a generic class was parameterized with.

So, the question is how to deal with type erasure in Scala?

Scala introduced Manifests somewhere around version 2.7. However, they had problems with not being able to represent certain types so Scala 2.10. deprecated them in favor of the more powerful TypeTags.

Type tags are divided into three separate types:

  • ClassTag
  • TypeTag
  • WeakTypeTag

ClassTag:

ClassTag[T] stores the erased class of a given type,T accessible via the runtime Class field. ClassTags are a weaker special case of scala.reflect.api.TypeTags#TypeTags, in that they wrap only the runtime class of a given type, whereas a TypeTag contains all static type information. That is, ClassTags are constructed from knowing only the top-level class of a type, without necessarily knowing all of its argument types.

This is particularly useful for instantiating generic Arrays whose element types are unknown at compile time.

For example,

ClassTag provides only the information needed to create types at runtime. If we ask for runtime class of List[Int], we can see that information about Int that the list is parameterized with is lost i.e. they don’t care about type erasure.

TypeTag:

If one wants “full” types, TypeTags should be used:

method tpe of TypeTag results in a full type

The primary use case of TypeTag is to give access to erased types. Scala’s TypeTags can give us details about type parameters that the Java compiler would normally erase.

WeakTypeTag:

WeakTypeTag[T] generalizes TypeTag[T]. TypeTag represents a concrete type which means it just allows fully instantiated types whereas WeakTypeTag allows any type.

It will give the following error:

But, if I use weakTypeTag, it will run fine

 

Please feel free to suggest or comment. Happy blogging 😉

References:

1. Scala in depth

2. Scala documentation


knoldus-advt-sticker


Written by 

I am a Software Consultant and has experience of more than 1.5 years. I like to study and write about latest technologies.

4 thoughts on “Back2Basics: Type Erasure in Scala3 min read

  1. To be honest, this blog post feels very incomplete. Ok, there are 3 different TypeTags. You say a few words about the difference, but you use the same example. My conclusion is that you can use whichever you want from the 3 possibilities? Can you extend with examples where you should use one of them instead of the others?

    ClassTags are a weaker special case of scala.reflect.api.TypeTags#TypeTags, in that they wrap only the runtime class of a given type, whereas a TypeTag contains all static type information. That is, ClassTags are constructed from knowing only the top-level class of a type, without necessarily knowing all of its argument types.

    well, if I know the difference from reading this sentence, then I probably wouldn’t need to open this blog post…

Comments are closed.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading