This is caused by how Arrays are represented on the JVM. You don’t need a ClassTag for list, because it is a normal class / trait, with a generic parameter. When you have a
List[String] and a
List[Int], type erasure will cause them to have the same class at runtime. All type checks are done at compile time. In Java, you are allowed to leave generic parameters off, getting an unchecked “raw type”, which is what you’ll have at runtime.
Arrays on the other hand have different runtime classes on the JVM. Array types are not erased, so an
Array[String] and and
Array[Int] are different classes at runtime. For that reason, you need to know the type at runtime to instantiate the class. This is what the
ClassTag does, it holds the type at runtime.
In Java, the difference is a bit more obvious, because of the different syntax for Arrays compared to generics, and because Arrays can have primitive types, which Java generics can not.