5 Replies Latest reply: May 17, 2012 11:47 AM by rukbat RSS

    Wildcards

    936584
      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
          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
            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
              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
                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
                  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.