0

I'm a bit confused about how Java generics handle inheritance / polymorphism.
It's fully possible to classcast Number to Integer but it seams not possible to classcast List<Number> to List<Integer>. Why ?

Here is my java code sample :

    Number n = new Integer(5);
    Integer i = (Integer) n; // No compilation or runtime error ==> for me it's normal

    Number n = new Long(5);
    Integer i = (Integer) n; // No compilation error but have a runtime error (ClassCastException) ==> for me it's normal

    List<Number> nList = new ArrayList<Number>();
    nList.add(Integer.valueOf(5));
    List<Integer> iList = (List <Integer>) nList; // Compilation error ==> WHYYYY ?!!

Thank's for your help.

EDIT :
This question is completely different from this one Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic? because my question is not why it's mandatory to write the class cast.

To be more specific, I call a function that returns a List<Change> where Change is an abstract super class so this list can contain ChangeItem or ChangeList or whatever subclass of Change depending on my request (parameters).

I know my request makes this function returning only ChangeItem so I want to convert it easily to return it from my function. I was thinking a class cast was the simplest way to do but it seems not possible because of compilation error.

Why it's possible to write and compil this :

    Number n = new Long(5);
    Integer i = (Integer) n;

While it's impossible to write and compil this :

    List<Number> nList = new ArrayList<Number>();
    nList.add(Integer.valueOf(5));
    List<Integer> iList = (List <Integer>) nList;

I just want the same ClassCastException if nList contains other things than Integer.

Community
  • 1
  • 1
Jocker
  • 268
  • 1
  • 2
  • 10
  • 6
    Why? Because the compiler can't prove that you didn't write `nList.add(Double.valueOf(5));` before the cast. – Andy Turner Mar 23 '17 at 16:28
  • It's actually more like: Because the compiler *can* prove that `List` is incompatible with `List`, i.e. `List` cannot possibly also be a `List`, similar to how `String s = (String) n` is a compilation error, because a `Number` cannot possibly also be a `String`. – Andreas Mar 23 '17 at 16:36
  • 1
    ... and if you did add a Double, you'll eventually get a ClassCastException, but it could be far away from the code in your snippet, and it'll look weird. You'll have something like `List myList = whatever(); Integer i = myList.get(0);` saying that a Double can't be converted to Integer -- classic recipe for a "huh?". The ClassCastException will be confusing, and the actual site of the problem (the `nList.add(Double.valueOf(5))`) will be hard to track down. – yshavit Mar 23 '17 at 16:37

0 Answers0