• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

super generic and for loop

 
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Reference S&B page 594.
I want to pass a List containg Dogs and (subclass) Terriers to a method.
But , whatever <type> I code at (1) <Animal> or <Dog> I get "incompatible type" at (2). I think this is a for-loop rather than a generics problem.
Thank you.
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your method accepts a list of Dog or any superclass - and that includes Object! If that is the case, how can your Objects make a sound?

You most likely want to change the list to List<? extends Animal> - a list of Animal or any subclass. Of course you need an Animal in the loop, not a Dog.

The general contract with wildcards is:
  • ? super X - you can pass X or any subclass, but not a superclass. For example, List<? super Dog> allows you to add Dog and Terrier objects but not Animal or Object objects - because the actual type could be Dog.
  • ? extends X - you can retrieve X or any superclass, but not a subclass (without casting). For example, from a List<? extends Animal> you can retrieve Animal and Object (through widening) objects, but not Dog or Terrier objects - because the actual type could be Cat which also extends Animal.
  •  
    Graeme Byers
    Ranch Hand
    Posts: 127
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thank you for your reply. Perhaps I did not explain correctly.
    S&B page 594 has code (below)which looks (at first glance) as if addAnimal() (because it takes a List as an argument) adds all the elements in the List. Of course it only adds one extra Dog to the list.

    What types must I code in the for-loop to add() all its elements ?
     
    Graeme Byers
    Ranch Hand
    Posts: 127
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Oops ! typo, read
    for (Dog d : animalListParm) { animalListParm.add(d) ; } // GB code (3)
     
    Ranch Hand
    Posts: 624
    IntelliJ IDE Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Graeme Byers:
    Oops ! typo, read
    for (Dog d : animalListParm) { animalListParm.add(d) ; } // GB code (3)



    You can fix the typo in your actual post. Click the edit icon at the top of the post to do such. This will make it easier for people to help you.
     
    Rob Spoor
    Sheriff
    Posts: 22783
    131
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Graeme Byers:
    What types must I code in the for-loop to add() all its elements ?


    Since the type is ? super Dog, that leaves three possible types:
    - Dog
    - Animal
    - Object

    Since you can't know which one it is, the widest one is the only one available when iterating: Object.

    Now of course, you can't add Object to your list - what if the actual type is Animal or Dog?

    Again the rules, but a bit more expanded:
  • ? super X:[LIST]
  • Add: X or a subclass / implementation. Basically anything that IS-A X
  • Iterate: only Object
  • ? extends X:
  • Add: nothing. You don't know the actual type, so you don't know what to add.
  • Iterate: X (or any superclass through widening)
  • X:
  • Add: X or a subclass / implementation. Basically anything that IS-A X
  • Iterate: X (or any superclass through widening)
  • [/LIST]

    Since you need to both add and iterate, you must limit your type to an exact class - no super or extends.


    As a side note, that code will most likely throw a ConcurrentModificationException. You are in fact modifying the list while iterating; that's not allowed. Imagine what would happen: you keep adding and adding and adding and adding, since every element that you encounter you add - and again, and again and again.
     
    Mark Vedder
    Ranch Hand
    Posts: 624
    IntelliJ IDE Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'll just add this to Rob's fine answer:

    I am not sure if your goal was to add all of a list to another list, or if it was to better understand generic wildcards. (I suspect it is the latter, in which case Rob's answer should do the job.) If it is the former, you can use the addAll(Collection) method from the Collection interface to do such. For example:




    As an additional note on the ConcurrentModificationException... the ideal way to resolve that would be to use the addAll method I show above. An alternative would be to use a conventional for loop, being sure to get teh collection's size before starting to iterate over it:

     
    I've never won anything before. Not even a tiny ad:
    a bit of art, as a gift, that will fit in a stocking
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic