This discussion is archived
12 Replies Latest reply: Jul 31, 2012 3:56 AM by 952795 RSS

Generic Methods

952795 Newbie
Currently Being Moderated
Hi everybody.

See screenshot:

http://img138.imageshack.us/img138/8782/50230399.png

Why answer "D" is correct?

Thank you.
Vitaliy.
  • 1. Re: Generic Methods
    EJP Guru
    Currently Being Moderated
    If you want an answer:

    1. Post your entire question here. Nobody is going to chase links for you.
    2. Don't crosspost.
    3. In a homework case like this, show some work of your own first. What do you think, and why?
  • 2. Re: Generic Methods
    952795 Newbie
    Currently Being Moderated
    This code compiles and runs without errors.
    import java.util.*;
    
    public class BackLister {
    
         public static <T> List<? extends T> backwards(List<T> input) {
              List<T> output = new LinkedList<T>();
              for (T t : input) {
                   output.add(0, t);
              }
              return output; // Why do not occurs compile-time error ?
         }
    
         public static void main(String[] args) {
              List<Long> longs = new LinkedList<Long>();
              longs.add(Long.valueOf("356"));
              System.out.println(backwards(longs));
         }
    
    }
    But why?
    I expected that the code will not compile...
  • 3. Re: Generic Methods
    EJP Guru
    Currently Being Moderated
    Obviously the problem is with your expectations, not the code, so tell us about your expectations. What errors were you expecting, and where, and why?
  • 4. Re: Generic Methods
    gimbal2 Guru
    Currently Being Moderated
    949792 wrote:
    But why?
    I expected that the code will not compile...
    "Why is water wet? I expected it to be dry!"

    What would your response be to this question?
  • 5. Re: Generic Methods
    952795 Newbie
    Currently Being Moderated
    Please explain why the method backwards (which has type List <? Extends T>) appropriate to the value of output (which has type List <T>). After all, types List <T> and List <? extends T> are incompatible. Because I try this code :
    import java.util.*;
    public class BackLister {
         public static <T> List<? extends T> backwards(List<T> input) {
              List<T> output = new LinkedList<T>();
              for (T t : input) {
                   output.add(0, t);
              }
              return output; 
         }
         public static void main(String[] args) {
              List<A> list1 = new LinkedList<A>();
              list1.add(new A());
              List<A> listA = backwards(list1); // Error: Type mismatch: cannot convert from List<capture#2-of ? extends A> to List<A>
              List<B> listB = backwards(list1); // Error: Type mismatch: cannot convert from List<capture#2-of ? extends A> to List<B>
         }
    }
    class A {}
    class B extends A {}
    And I received an error.
  • 6. Re: Generic Methods
    EJP Guru
    Currently Being Moderated
    After all, types List <T> and List <? extends T> are incompatible.
    Too broad. You can assign in one direction but not the other.
  • 7. Re: Generic Methods
    952795 Newbie
    Currently Being Moderated
    But why I get an error:
    cannot convert from List<capture#2-of ? extends A> to List<B>
    After all, class B extends A.
  • 8. Re: Generic Methods
    EJP Guru
    Currently Being Moderated
    But B doesn't extend ?. ? stands for some unknown class that extends A. Could be B, could be anything.
  • 9. Re: Generic Methods
    gimbal2 Guru
    Currently Being Moderated
    EJP wrote:
    But B doesn't extend ?. ? stands for some unknown class that extends A. Could be B, could be anything.
    Takes me back to school. "A cow is an animal, but an animal is not necessarily a cow" :)
  • 10. Re: Generic Methods
    952795 Newbie
    Currently Being Moderated
    Unfortunately you do not understand me.
    I'll try to explain another.

    I added the method "backwards2".
    import java.util.*;
    public class BackLister {
         public static <T> List<? extends  T> backwards1(List<T> input) {
              List<T> output = new LinkedList<T>();
              for (T t : input) {
                   output.add(0, t);
              }
              return output; 
         }
         public static List<B> backwards2(List<A> input) {
              List<A> output = new LinkedList<A>();
              for (A t : input) {
                   output.add(0, t);
              }
              return output;  // Type mismatch: cannot convert from List<A> to List<B>     
    
         }     
         public static void main(String[] args) {
         }
    }
    class A {}
    class B extends A {}
    The compiler shows an error:
    "Type mismatch: cannot convert from List <A> to List <B>"
    The reason for the error in the method "backwards2" is obvious.
    But I do not understand why the compiler does not show the same error in the method "*backwards1*".
  • 11. Re: Generic Methods
    EJP Guru
    Currently Being Moderated
    Unfortunately you do not understand me.
    I don't have to understand you. It is you who has the misunderstandings and incorrect expectations, not me. Your task is to understand me, and everything else you're being told here. You are now asking a new question as far as I can see. That's not my fault.
    The reason for the error in the method "backwards2" is obvious.
    But I do not understand why the compiler does not show the same error in the method "*backwards1*".
    Because it's not the same error. List&lt;? extends A&gt; means a list of something unknown that could be A or anything that extends A. So it's OK to return a List&lt;A&gt; to satisfy the contract. List&lt;B&gt; means a list of objects that are instances of B or its subclasses. A List&lt;A&gt; cannot satisfy that contract.
  • 12. Re: Generic Methods
    952795 Newbie
    Currently Being Moderated
    Thanks for the answers.

Legend

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