0

Generics are knowingly meant for stronger type checking at compile time. However, while studying the official Java tutorial, I ran into this:

However, in some cases the compiler knows that a type parameter is always valid and allows the cast. For example:

List<String> l1 = ...;
ArrayList<String> l2 = (ArrayList<String>)l1;  // OK

from http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast.

I've tried and tested this (which fully reflects the documentation):

List<String> l1 = new LinkedList<String>();
ArrayList<String> l2 = (ArrayList<String>)l1;  // OK

Although everything is pretty explicit (no assignment to an Object variable, no wilcarding, etc), the compiler fails to predict the runtime error that shows up afterwards:

Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList cannot be cast to java.util.ArrayList

100% puzzled.

Callistus
  • 11
  • 3
  • [What is the difference between up-casting and down-casting with respect to class variable](http://stackoverflow.com/questions/23414090/what-is-the-difference-between-up-casting-and-down-casting-with-respect-to-class)? – Sotirios Delimanolis Nov 03 '14 at 23:12
  • 5
    You're attempting to cast a `List` to `ArrayList`, which gives a runtime exception. Why would there be a compiler error? – Vince Nov 03 '14 at 23:12
  • Thank everybody for the clarification. `In some cases`, in the tutorial, was a bit vague. After this I google'd the tutorial site for `downcast` and `upcast` - found nothing, so thanks again for the plus. – Callistus Nov 03 '14 at 23:55

1 Answers1

1

Reread the link -- it's not stating you can cast a LinkedList to an ArrayList. It's stating that you can downcast a List of String to the (presumably programmer-known) type of ArrayList of String. What they're attempting to illustrate is the difference between the generic type parameters. Their first example shows casting from a collection of Integer to a collection of Number, which is not allowed.

Typically, you cannot cast to a parameterized type unless it is parameterized by unbounded wildcards. For example:

List li = new ArrayList<>(); List ln = (List) li; // compile-time error

However, in some cases the compiler knows that a type parameter is always valid and allows the cast. For example:

List l1 = ...; ArrayList l2 = (ArrayList)l1; // OK

Thorn G
  • 12,620
  • 2
  • 44
  • 56
  • Thank you for the clarification. `In some cases`, in the tutorial, was a bit vague. After this I google'd the tutorial site for `downcast` and `upcast` - found nothing, so thanks again for the plus. – Callistus Nov 03 '14 at 23:56