In languages like Java that use type erasure for generics, some casts are considered unchecked. One example is casting a value of Object to List<String>. On the other hand, casting from Iterable<String> to List<String> is allowed because the type parameter matches. Casting Object to List<?> is also allowed due to the wildcard.

In JLS, it states

A narrowing reference conversion from a type S to a parameterized class or interface type T is unchecked, unless at least one of the following is true:

  • All of the type arguments of T are unbounded wildcards.
  • T <: S, and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T.
  • What is required to check the second criteria listed above?
  • Is there a well known algorithm for performing this check?
  • What edge cases need to be considered?

1 Answer 1


The second criterion essentially checks the subtyping rule of your language. In Java, it's inheritance plus covariance. For instance:

  • If type A extends/implements type B, then A :< B (same when adding generic parameters)
  • If A :< B then A[] :< B[] (this rule is true in Java, but is flawed)

So, an algorithm for checking this would be a graph-theoretic algorithm that detects if a node is an ancestor of another node.

Regarding edge cases, you may have to deal with special subtyping rules, for example, int is a subtype of long (check the Liskov substitution principle!), but there is no inheritance between them.

  • $\begingroup$ This doesn't really answer the question. I think it is clear why an unchecked cast is a problem. I'm more interested in how the compiler detects that the cast is unchecked. $\endgroup$
    – MI3Guy
    Commented May 17, 2023 at 14:42
  • $\begingroup$ @MI3Guy hi, I rewrote my answer. $\endgroup$
    – ice1000
    Commented May 17, 2023 at 14:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .