Hacker News new | ask | show | jobs
by kroltan 832 days ago
I'm assuming because of erasure?

In C#, List<T> and List<U> follows the same assignment rules as T and U, and at runtime are represented by distinct types. That means that going from List<T> to object to List<U> causes a runtime error at the point of casting.

In Java, every generic type is erased to object at runtime, so the runtime type is just List, and you could cast List<T> to object to List<U> and only get an error later, when you try calling U methods on the contents of the list.

(Yes in C# List is a concrete vector type and in Java it is a random-access collection interface, but that is not relevant here)

2 comments

The delayed error happens only when you ignore unchecked warnings, which would have been compiler errors if not for backward compatibility. One can turn them into errors with `-Werror`.

The type erasure has occasional benefits, like allowing objects that are polymorphic in their type argument when that’s still safe semantically (a simple example being emptyList() and emptySet()), where the type system isn’t expressive enough to otherwise allow it. This is a bit like the “unsafe” escape in other languages.

if T and U don't have the same erasure the compiler will forbid the cast

if they do the compiler will warn you that an List<T> to List<U> cast is naughty

but in that case the only methods you can call on it are that of the erased type anyway

in practice I don't think I've ever seen a bug as a result of this type of erasure (and I've probably worked with at least several million lines of Java)