This discussion is archived
5 Replies Latest reply: May 17, 2012 9:47 AM by rukbat RSS

Wildcards

936584 Newbie
Currently Being Moderated
Hi,

I have a method like this:
     private static void getAnimalCages(List<? extends Animal> someCage) {     
//          List<Dog> dogCage = (List<Cat>) someCage; Compiler-Time error
          List<Dog> dogCage = (List<Dog>) someCage; // It should thwrow a runtime error, but it's perfect
     }
As you can see, in the first line of the method, the commented line, I try to assign a List<Cat> to a List<Dog>, which obviously gives me a compile error, nothing new under the sun.

In the second line, I assignd the List<? extends Animal> parameter to a List<Dog> making a manual cast, because I'm expecting a List<Dog>.

But I'm sending a List<Cat> to the method getAnimalCages, as follows:
List<Cat> catCage = new ArrayList<Cat>();
getAnimalCages(catCage);
As you can see, I'm not sending a List<Dog> but a List<Cat> to the method, and the program runs perfectly.

My question is: Why, if I'm sending a List<Cat> to the method, the next cast in the method works well?
List<Dog> dogCage = (List<Dog>) someCage;
Thanks in advance.
  • 1. Re: Wildcards
    800357 Newbie
    Currently Being Moderated
    That's because of "type erasure": the types are used by the compiler at compile-time to check for errors, but thereafter are "erased", i.e. no information about the generic types exists at runtime (for backwards compatibility with pre-generics Java code). Thus, at runtime, the only thing that's known is that you passed in a List to the method, and you're casting a List to a List. That will work. You might run into trouble when you start to work with items from the list though (since you're expecting them to be Dogs but they are Cats). Check the Generics tutorial for more info on type erasure.

    The problem is not detected at compile time, since all separate steps are valid:
    - List<Cat> is a List<? extends Animal>
    - List<Dog> is a List<? extends Animal>
  • 2. Re: Wildcards
    jtahlborn Expert
    Currently Being Moderated
    797354 wrote:
    The problem is not detected at compile time, since all separate steps are valid:
    - List<Cat> is a List<? extends Animal>
    - List<Dog> is a List<? extends Animal>
    actually, the problem is detected at compile time. This line:
    List<Dog> dogCage = (List<Dog>) someCage;
    should be generating an "unchecked" warning. the OP either has warnings disabled or is ignoring them.
  • 3. Re: Wildcards
    800357 Newbie
    Currently Being Moderated
    actually, the problem is detected at compile time.
    Sorry, you're right. I meant to say there is no compile error.
  • 4. Re: Wildcards
    936584 Newbie
    Currently Being Moderated
    Hi guys,

    Thanks a lot for your answers, they were really helpful.

    By the way, Who is or what is OP? The one who is ignoring the warnings.

    Best regards.
  • 5. Re: Wildcards
    rukbat Guru Moderator
    Currently Being Moderated
    933581 wrote:

    By the way, Who is or what is OP? The one who is ...
    "OP" is the original poster. That is a term you will see in every forum you might surf to on the Internet.
    They are the person that initiated this thread.
    In this example, it is you.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points