value classes can be used to achieve type safety without the overhead of unboxing.
I had the impression that in runtime such types/classes would "not exist", being seen as simple types (for instance, a value class case class X(i: Int) extends AnyVal
would be a simple Int
on runtime).
But if you do call a .toString
method on a value class instance it would print something like:
scala> val myValueClass = X(3)
myValueClass: X = 3
scala> myValueClass.toString
res5: String = X(3)
so I guess the compiler includes some information after all?
Not really. The compiler creates a static method (in Scala this corresponds to the class's companion object) which is called with your int value as a parameter in order to simulate calling a method on your value class-typed object.
Your value class itself only exists in the source code. In compiled bytecode an actual primitive int is used and static methods are called rather than new object instances with real method calls. You can read more about this mechanism here.