Given the following object:
object Foo {
val bar: List[Int] = List(1, 2, 3)
}
When we compile this file to JVM bytecode, because of type erasure and due to the fact that Java does not support primitive types as parameters for generic types, this gets translated into a List<Object>
.
We can see this by compiling and inspecting the .class
with javap -l
:
public static com.yuvalitzchakov.github.Foo$ MODULE$;
descriptor: Lcom/yuvalitzchakov/github/Foo$;
flags: ACC_PUBLIC, ACC_STATIC
public scala.collection.immutable.List<java.lang.Object> bar();
descriptor: ()Lscala/collection/immutable/List;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field bar:Lscala/collection/immutable/List;
4: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/yuvalitzchakov/github/Foo$;
Signature: #17 // ()Lscala/collection/immutable/List<Ljava/lang/Object;>;
But, if we compile this into a JAR file and later take it as a dependency in a different Scala project and try to set Foo.bar
to a different value, the Scala compiler will infer this type as List[Int]
, not List[Object]
:
After browsing around the .class
file, I could not find the information on the type parameter which would allow the Scala compiler to successfully infer this as List[Int]
.
Where is this metadata stored such that we can refer to this type as an actual List[Int]
instead of List[Object]
?