14 Replies Latest reply: Mar 9, 2010 7:17 PM by 843793 RSS

    When to use wildcards over types?

    796386
      Hi,
      Just a bit confused as to when to use wildcard over types.
      For example, I have a class which groups different types of Animals together (note it won't extends List or Collection etc).
      I have a base Animal class with different types of Animals, such as Cat, Dog etc. Some of the animals then have further sometypes such as Terrier and JackRussell being sub types of Dog. It is okay to group different types of Dogs if the Animals are all dogs.

      So I want something like:
      public class Animals<T extends Animal> {
           public void add(T animal) {
                      ...
           }
      
           public void remove(T animal) {
                      ....
           }
           
           public T get(int i){
           ...
           }
      }
      Or should I do something similar using the wildcard "?" notation?

      Why are the pro / cons?

      Thanks.
        • 1. Re: When to use wildcards over types?
          791266
          I don't see why you would use generics at all in this case.

          Kaj
          • 2. Re: When to use wildcards over types?
            843793
            Kajbj, why not?
            • 3. Re: When to use wildcards over types?
              EJP
              That's the wrong question. The question is why would you use Generics ? What feature provided by Generics is required here?
              • 4. Re: When to use wildcards over types?
                843793
                For the same reason that push someone to use generics for a container: preserving type information.
                In fact, one could just use Animal as only data type, like
                public Animal get(int index) { ... }
                public void put(Animal a) { ... }
                But let's assume you have a hierarchy like
                interface Animal { void move(); }
                interface Fish extends Animal { void swim(); }
                interface Quadruped extends Animal { void run(); }
                class Tuna implements Fish { ... }
                class Goldfish implements Fish { ... }
                class Dog implements Quadruped { ... }
                In this case using generics one can specialize the class and use it for fishes or quadrupeds, without losing that information and without requiring any cast.

                That's how I see it, at least :)

                EDIT:
                By the way, I say this because I'm developing a project and I use generics in the same way: I've some basic classes, and some subclasses that behave in a particular way. But the code must be reusable, so other subclasses may be used instead (also, it ease my future work to use generics now, because any change in the base class would only require a change in the class signature (<T extends NewRequiredType>)).

                Even if I'm doing this wrong, because generics aren't mean to be used like that (but I don't see why they would), I've experienced many advantages in using generics in the way I explained above, as they introduce constraints (which - I came from C++ - Are A Good Thing) improving type safety, give faster modification times and make code more reusable.
                As not being a Java expert, I'm not considering the speed of the produced code, and the "code writing overhead" when using generics is rather low.

                I explained why would I use generics. Now tell me: why not use them? :)

                Edited by: akithered on Feb 14, 2010 2:34 AM
                • 5. Re: When to use wildcards over types?
                  843793
                  So in other words it's a java.util.List equivalent that only allows Animal-elements.

                  What I would like to know is what the wildcards alternative is supposed to be? Could you provide a sketch?

                  With kind regards
                  Ben
                  • 6. Re: When to use wildcards over types?
                    843793
                    BenSchulz wrote:
                    So in other words it's a java.util.List equivalent that only allows Animal-elements.
                    Well I think it's not exactly like that, because for Animal only elements this code would do:
                    public class Something {
                        public void set(Animal a) { ... }
                        public Animal get(int i) { ... }
                    }
                    Which loose (i.e. require later testing and casting, I guess) the data information when using a subclass like Quadruped or Fish.

                    About the wildcards: sorry but I still don't feel so comfortable with wildcards right now so I won't try to give an answer.
                    I'll wait for an answer from more experts, too.
                    • 7. Re: When to use wildcards over types?
                      791266
                      akithered wrote:
                      Kajbj, why not?
                      Because he said:
                      "I have a class which groups different types of Animals together"
                      So the class groups Animals together, but the only common base for them is Animal, so why would he use generics? It would be a different ball game if he said that it groups animals of same type.
                      • 8. Re: When to use wildcards over types?
                        843793
                        kajbj wrote:
                        akithered wrote:
                        Kajbj, why not?
                        Because he said:
                        "I have a class which groups different types of Animals together"
                        So the class groups Animals together, but the only common base for them is Animal, so why would he use generics? It would be a different ball game if he said that it groups animals of same type.
                        Well, he didn't said there couldn't be groups :D

                        Edited by: akithered on Feb 14, 2010 11:52 AM
                        • 9. Re: When to use wildcards over types?
                          843793
                          akithered wrote:
                          BenSchulz wrote:
                          So in other words it's a java.util.List equivalent that only allows Animal-elements.
                          Well I think it's not exactly like that, because for Animal only elements this code would do:
                          public class Something {
                          public void set(Animal a) { ... }
                          public Animal get(int i) { ... }
                          }
                          Which loose (i.e. require later testing and casting, I guess) the data information when using a subclass like Quadruped or Fish.
                          I should have been more clear. I was refering to the Animals type declaration of your original post and meant to say: So in other words it's a java.util.List equivalent that only allows element types (Ts) which are subtypes of Animal.
                          About the wildcards: sorry but I still don't feel so comfortable with wildcards right now so I won't try to give an answer.
                          I think that's the crux of the matter; you're not sure about wildcards. Wildcards come into play in client code (i.e. code that utilizes the Animals class) and not generally in your declaration of Animals. ("Not generally" is meant to leave room for bulk operations such as addAll(Animals<? extends T> as).)

                          EDIT: I just now realize you're not the OP -- sorry.

                          With kind regards
                          Ben

                          Edited by: BenSchulz on Feb 14, 2010 11:50 AM
                          • 10. Re: When to use wildcards over types?
                            843793
                            akithered wrote:
                            kajbj wrote:
                            akithered wrote:
                            Kajbj, why not?
                            Because he said:
                            "I have a class which groups different types of Animals together"
                            So the class groups Animals together, but the only common base for them is Animal, so why would he use generics? It would be a different ball game if he said that it groups animals of same type.
                            Well, he didn't said there couldn't be groups :D
                            I'm sorry, as we both didn't read well his post: he did say there could be groups:
                            I have a base Animal class with different types of Animals, such as Cat, Dog etc. Some of the animals then have further sometypes such as Terrier and JackRussell being sub types of Dog. It is okay to group different types of Dogs if the Animals are all dogs.
                            That's the use I was thinking about: if all animals are dogs, then it's ok to use Dog as specific subtype of animal.
                            • 11. Re: When to use wildcards over types?
                              791266
                              akithered wrote:
                              akithered wrote:
                              kajbj wrote:
                              akithered wrote:
                              Kajbj, why not?
                              Because he said:
                              "I have a class which groups different types of Animals together"
                              So the class groups Animals together, but the only common base for them is Animal, so why would he use generics? It would be a different ball game if he said that it groups animals of same type.
                              Well, he didn't said there couldn't be groups :D
                              I'm sorry, as we both didn't read well his post: he did say there could be groups:
                              I have a base Animal class with different types of Animals, such as Cat, Dog etc. Some of the animals then have further sometypes such as Terrier and JackRussell being sub types of Dog. It is okay to group different types of Dogs if the Animals are all dogs.
                              That's the use I was thinking about: if all animals are dogs, then it's ok to use Dog as specific subtype of animal.
                              Hard to know what the OP wanted to say, but that sounds like a specific case to me, and the general case is that he has animals of different type.
                              • 12. Re: When to use wildcards over types?
                                843793
                                Ok, maybe it is a specific case, but it could happen, couldn't it?
                                Would you write different codes for all the specific cases (Dogs, Cats, Quadrupeds or Fishes) that could happen? I don't think so.
                                • 13. Re: When to use wildcards over types?
                                  791266
                                  akithered wrote:
                                  Ok, maybe it is a specific case, but it could happen, couldn't it?
                                  Yes it could, but I wouldn't make the class generic unless I would need it, and I wouldn't need it if I mostly grouped different types of animals.
                                  • 14. Re: When to use wildcards over types?
                                    843793
                                    Taking a stab at the original question here (when do you use a wildcard versus a named type)

                                    You use a named type when you want to be sure all references to objects of this type refer to the same class.

                                    So if you create an Animals<Dog>, all T's now refer to Dog.

                                    You would use <? super SomeClass> when the only constraint you need on the object is that it is some subclass of SomeClass.

                                    In your situation you're probably doing it the right way.

                                    EDIT: Reply #9 has a better explanation!

                                    Edited by: fragorl on Mar 9, 2010 5:15 PM

                                    Edited by: fragorl on Mar 9, 2010 5:17 PM