2 Replies Latest reply: May 8, 2008 8:47 AM by 807591 RSS

    return type using generic container with wildcard cause compiler error

    807591
      Hi guys,
      I'm studying for SCJP, and one of the sample code fragment in the book say this is wrong but i dont understand why
      public static void main(String[] args)
      {
           ArrayList<Integer> input = null;         
           List<Number> output = null;             //line 4
           output = proces(input);                    //line 5
      }
      //------------------------------------------------
          public static <E extends Number> List<? super E> proces(List<E> nums)
          {
           List<Number> n = new ArrayList<Number>();
           return n;
          }
      I know if i run this it may give NullPointerException but at least the code should compile. However, i am getting
      found   : java.util.List<capture#890 of ? super java.lang.Integer>
      required: java.util.List<java.lang.Number>
              output = proces(input);
      My code does return a List<Number> and put it in a List<Number> so why it is saying i am returning super of Integer?

      The book also suggest to change line 4 to
      List<Integer> output = null;
      to make it compile but it give me similar error
      Any explaination?
        • 1. Re: return type using generic container with wildcard cause compiler error
          807591
          lnthai2002 wrote:
          However, i am getting
          found   : java.util.List<capture#890 of ? super java.lang.Integer>
          required: java.util.List<java.lang.Number>
          output = proces(input);
          My code does return a List<Number> and put it in a List<Number> so why it is saying i am returning super of Integer?
          Um... because that's what your method is declared to return: a List<? super E>, where E is inferred to be Integer.

          >
          The book also suggest to change line 4 to
          List<Integer> output = null;
          to make it compile but it give me similar error
          Any explaination?
          A List<? super Integer> is not necessarily a List<Integer>. What if it's actually a List<Number> (which it really is) or List<Object>?
          • 2. Re: return type using generic container with wildcard cause compiler error
            807591
            my method is declared to return List<? super E> so inside the method, i can return List<Number> given that E refer to an Integer, right? Because Number is superclass of Integer.
            However, since you raise the question about the left-hand side (output) being a fixed type <Integer> while the right hand side is open to return any thing above E - Integer in this case, i think compiler gonna tell when u r trying to assign the incompatible type to the right hand side. But my my example, both the left hand and right hand are the same, just the declaration of the right hand (the return type of the method) is cryptic.
            The book say it's possible to use <? super E> in the return type, but I have not succeed in any method declared as such.
            Another thing i found strange with the wild card is that it doesnt seem to follow any rules, for example, the following code works:
                    Human g1 = new Girl("cindy");//2 humans
                 Human b1 = new Boy("bean");
                 //so the right hand must be declared as Human
                 //but the left hand can be ? because we dont add, we simply use and Human is a subclass of Human
                 GenericPair<? extends Human,? extends Human> p1 = new GenericPair<Human,Human>(g1,b1);
            But this one doesnt work:
                    List<? extends Human> list1 = new ArrayList<Human>();
                 list1.add(new Boy("smith"));
                 list1.add(new Human("eve"));
            the error is: cannot find method add(testGeneric.Boy)
            Given that class Boy and Girl extends Human
            When i learned generic, i though the rule is "When we USE generic container/class, polymorphisms is allowed-for example, container can be declared to contain superclass object, but we can add object of child class. However, when we DEFINE generic class, polymorphisms is not guaranteed inside the definition"
            Any other explanation? I am very appreciate if anyone can teach me the easy way to remember how generic work
            Thx
            Thai