Rectifying an upper bounded class type Iterable and upper bounded wildcard List field Iterator type












1















I'm trying to find the correct generics and wildcard arrangement to make this work. The types have been changed and all other code has removed to keep this as simple as possible.



Here I have a generic class with an upper bound of Number that implements Iterable. It contains a List of the generic type.



I want to pass in a List of any Number subclass, and return the Iterator of that type from the List field.



Here's the basic idea that obviously doesn't work.



class GenericQuestion<T extends Number> implements Iterable<T> {
List<T> numbers;

GenericQuestion(List<T> number) {
this.numbers = number;
}

public Iterator<T> iterator() {
return numbers.iterator();
}

static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) { // <---- error
System.out.println(n.byteValue());
}
}
}


This give the expected error



incompatible types: ArrayList<Integer> cannot be converted to List<Number>


Upper-bounded wildcards to the rescue! Almost...



class GenericQuestion<T extends Number> implements Iterable<T> {
List<? extends T> numbers;

GenericQuestion(List<? extends T> number) {
this.numbers = number;
}

public Iterator<T> iterator() {
return numbers.iterator(); // <----- error
}

static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
System.out.println(n.byteValue());
}
}
}


Now I'm getting hung up on the iterator types conflicting.



incompatible types: Iterator<CAP#1> cannot be converted to Iterator<T>
where T is a type-variable:
T extends Number declared in class GenericQuestion
where CAP#1 is a fresh type-variable:
CAP#1 extends T from capture of ? extends T


Now logically I'm pretty sure it would be perfectly safe to just force cast the returned iterator to type (Iterator<T>),
but I'd rather do this the "right" way. I've tried all sorts of things. Here was another desperate attempt that still didn't work.



class GenericQuestion<T extends Number> implements Iterable<T> {
List<T> numbers;

<U extends Number> GenericQuestion(List<U> number) {
this.numbers = number; // <----- error
}

public Iterator<T> iterator() {
return numbers.iterator();
}

static void main() {
for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
System.out.println(n.byteValue());
}
}
}


The error.



incompatible types: List<U> cannot be converted to List<T>
where U,T are type-variables:
U extends Number declared in constructor <U>GenericQuestion(List<U>)
T extends Number declared in class GenericQuestion


I thought maybe a helper function could bridge the gap, but didn't have any luck with my attempts.



This doesn't seem like it should be so hard. Is force casting really the way to go? Or is there a generic declaration that will make this all work together?










share|improve this question



























    1















    I'm trying to find the correct generics and wildcard arrangement to make this work. The types have been changed and all other code has removed to keep this as simple as possible.



    Here I have a generic class with an upper bound of Number that implements Iterable. It contains a List of the generic type.



    I want to pass in a List of any Number subclass, and return the Iterator of that type from the List field.



    Here's the basic idea that obviously doesn't work.



    class GenericQuestion<T extends Number> implements Iterable<T> {
    List<T> numbers;

    GenericQuestion(List<T> number) {
    this.numbers = number;
    }

    public Iterator<T> iterator() {
    return numbers.iterator();
    }

    static void main() {
    for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) { // <---- error
    System.out.println(n.byteValue());
    }
    }
    }


    This give the expected error



    incompatible types: ArrayList<Integer> cannot be converted to List<Number>


    Upper-bounded wildcards to the rescue! Almost...



    class GenericQuestion<T extends Number> implements Iterable<T> {
    List<? extends T> numbers;

    GenericQuestion(List<? extends T> number) {
    this.numbers = number;
    }

    public Iterator<T> iterator() {
    return numbers.iterator(); // <----- error
    }

    static void main() {
    for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
    System.out.println(n.byteValue());
    }
    }
    }


    Now I'm getting hung up on the iterator types conflicting.



    incompatible types: Iterator<CAP#1> cannot be converted to Iterator<T>
    where T is a type-variable:
    T extends Number declared in class GenericQuestion
    where CAP#1 is a fresh type-variable:
    CAP#1 extends T from capture of ? extends T


    Now logically I'm pretty sure it would be perfectly safe to just force cast the returned iterator to type (Iterator<T>),
    but I'd rather do this the "right" way. I've tried all sorts of things. Here was another desperate attempt that still didn't work.



    class GenericQuestion<T extends Number> implements Iterable<T> {
    List<T> numbers;

    <U extends Number> GenericQuestion(List<U> number) {
    this.numbers = number; // <----- error
    }

    public Iterator<T> iterator() {
    return numbers.iterator();
    }

    static void main() {
    for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
    System.out.println(n.byteValue());
    }
    }
    }


    The error.



    incompatible types: List<U> cannot be converted to List<T>
    where U,T are type-variables:
    U extends Number declared in constructor <U>GenericQuestion(List<U>)
    T extends Number declared in class GenericQuestion


    I thought maybe a helper function could bridge the gap, but didn't have any luck with my attempts.



    This doesn't seem like it should be so hard. Is force casting really the way to go? Or is there a generic declaration that will make this all work together?










    share|improve this question

























      1












      1








      1








      I'm trying to find the correct generics and wildcard arrangement to make this work. The types have been changed and all other code has removed to keep this as simple as possible.



      Here I have a generic class with an upper bound of Number that implements Iterable. It contains a List of the generic type.



      I want to pass in a List of any Number subclass, and return the Iterator of that type from the List field.



      Here's the basic idea that obviously doesn't work.



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<T> numbers;

      GenericQuestion(List<T> number) {
      this.numbers = number;
      }

      public Iterator<T> iterator() {
      return numbers.iterator();
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) { // <---- error
      System.out.println(n.byteValue());
      }
      }
      }


      This give the expected error



      incompatible types: ArrayList<Integer> cannot be converted to List<Number>


      Upper-bounded wildcards to the rescue! Almost...



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<? extends T> numbers;

      GenericQuestion(List<? extends T> number) {
      this.numbers = number;
      }

      public Iterator<T> iterator() {
      return numbers.iterator(); // <----- error
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
      System.out.println(n.byteValue());
      }
      }
      }


      Now I'm getting hung up on the iterator types conflicting.



      incompatible types: Iterator<CAP#1> cannot be converted to Iterator<T>
      where T is a type-variable:
      T extends Number declared in class GenericQuestion
      where CAP#1 is a fresh type-variable:
      CAP#1 extends T from capture of ? extends T


      Now logically I'm pretty sure it would be perfectly safe to just force cast the returned iterator to type (Iterator<T>),
      but I'd rather do this the "right" way. I've tried all sorts of things. Here was another desperate attempt that still didn't work.



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<T> numbers;

      <U extends Number> GenericQuestion(List<U> number) {
      this.numbers = number; // <----- error
      }

      public Iterator<T> iterator() {
      return numbers.iterator();
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
      System.out.println(n.byteValue());
      }
      }
      }


      The error.



      incompatible types: List<U> cannot be converted to List<T>
      where U,T are type-variables:
      U extends Number declared in constructor <U>GenericQuestion(List<U>)
      T extends Number declared in class GenericQuestion


      I thought maybe a helper function could bridge the gap, but didn't have any luck with my attempts.



      This doesn't seem like it should be so hard. Is force casting really the way to go? Or is there a generic declaration that will make this all work together?










      share|improve this question














      I'm trying to find the correct generics and wildcard arrangement to make this work. The types have been changed and all other code has removed to keep this as simple as possible.



      Here I have a generic class with an upper bound of Number that implements Iterable. It contains a List of the generic type.



      I want to pass in a List of any Number subclass, and return the Iterator of that type from the List field.



      Here's the basic idea that obviously doesn't work.



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<T> numbers;

      GenericQuestion(List<T> number) {
      this.numbers = number;
      }

      public Iterator<T> iterator() {
      return numbers.iterator();
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) { // <---- error
      System.out.println(n.byteValue());
      }
      }
      }


      This give the expected error



      incompatible types: ArrayList<Integer> cannot be converted to List<Number>


      Upper-bounded wildcards to the rescue! Almost...



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<? extends T> numbers;

      GenericQuestion(List<? extends T> number) {
      this.numbers = number;
      }

      public Iterator<T> iterator() {
      return numbers.iterator(); // <----- error
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
      System.out.println(n.byteValue());
      }
      }
      }


      Now I'm getting hung up on the iterator types conflicting.



      incompatible types: Iterator<CAP#1> cannot be converted to Iterator<T>
      where T is a type-variable:
      T extends Number declared in class GenericQuestion
      where CAP#1 is a fresh type-variable:
      CAP#1 extends T from capture of ? extends T


      Now logically I'm pretty sure it would be perfectly safe to just force cast the returned iterator to type (Iterator<T>),
      but I'd rather do this the "right" way. I've tried all sorts of things. Here was another desperate attempt that still didn't work.



      class GenericQuestion<T extends Number> implements Iterable<T> {
      List<T> numbers;

      <U extends Number> GenericQuestion(List<U> number) {
      this.numbers = number; // <----- error
      }

      public Iterator<T> iterator() {
      return numbers.iterator();
      }

      static void main() {
      for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
      System.out.println(n.byteValue());
      }
      }
      }


      The error.



      incompatible types: List<U> cannot be converted to List<T>
      where U,T are type-variables:
      U extends Number declared in constructor <U>GenericQuestion(List<U>)
      T extends Number declared in class GenericQuestion


      I thought maybe a helper function could bridge the gap, but didn't have any luck with my attempts.



      This doesn't seem like it should be so hard. Is force casting really the way to go? Or is there a generic declaration that will make this all work together?







      java generics






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 18 '18 at 8:53









      m35m35

      10528




      10528
























          3 Answers
          3






          active

          oldest

          votes


















          1














          I think you must have some type unsafe code somewhere if you want variance on T.



          The thing that causes this limitation is Iterable<T>. It requires a method Iterator<T> iterator(). You can't be certain that your Iterator<? extends T> can be converted to Iterator<T> because the only case in which this is possible is when your Iterator<? extends T> is a Iterator<T> at runtime. You probably already understand the fact that A<T> cannot be converted to A<U> even if T extends U.



          If instead you created your own MyIterable<T> interface, you can do this:



          class GenericQuestion<T extends Number> implements MyIterable<T> {
          List<? extends T> numbers;

          GenericQuestion(List<? extends T> number) {
          this.numbers = number;
          }

          public Iterator<? extends T> iterator() {
          return numbers.iterator();
          }

          static void main() {
          GenericQuestion<Number> q = new GenericQuestion<>(new ArrayList<Integer>());
          Iterator<? extends Number> iter = q.iterator();
          System.out.println(iter.next().byteValue());
          }
          }

          interface MyIterable<T> {
          Iterator<? extends T> iterator();
          }


          But as you can see, you can't use MyIterable with a for loop.



          Therefore, you either don't allow new GenericQuestion<Number>(new ArrayList<Integer>()), or you write type unsafe code.






          share|improve this answer
























          • I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

            – m35
            Jan 28 at 4:18



















          1














          A litle change to your test so that it is not trying to force to GenericQuestion<Number> (but to let infer type instead):



          for (Number n : new GenericQuestion<>(new ArrayList<Integer>())) {


          Also you could change the declaration for the List type of iterable, like:



          class GenericQuestion<T extends Number, L extends List<T>>
          implements Iterable<T> {

          private L numbers;

          GenericQuestion(L number) {
          this.numbers = number;
          }





          share|improve this answer


























          • I removed code to keep the question simple. A list is required in the full implementation.

            – m35
            Nov 18 '18 at 9:21











          • Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

            – m35
            Jan 28 at 4:21



















          0














          Another solution I found was to wrap the wildcard iterator with an iterator of the base type. I suspect this is technically how you're supposed to handle this situation.



          class GenericQuestion<T extends Number> implements Iterable<T> {
          List<? extends T> numbers;

          GenericQuestion(List<? extends T> number) {
          this.numbers = number;
          }

          public Iterator<T> iterator() {
          return new Iterator<T>() {
          Iterator<? extends T> iter = numbers.iterator();
          public boolean hasNext() {
          return iter.hasNext();
          }

          public T next() {
          return iter.next();
          }

          public void remove() {
          iter.remove();
          }
          };
          }

          static void main() {
          for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
          System.out.println(n.byteValue());
          }
          }
          }





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53359229%2frectifying-an-upper-bounded-class-type-iterable-and-upper-bounded-wildcard-list%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            I think you must have some type unsafe code somewhere if you want variance on T.



            The thing that causes this limitation is Iterable<T>. It requires a method Iterator<T> iterator(). You can't be certain that your Iterator<? extends T> can be converted to Iterator<T> because the only case in which this is possible is when your Iterator<? extends T> is a Iterator<T> at runtime. You probably already understand the fact that A<T> cannot be converted to A<U> even if T extends U.



            If instead you created your own MyIterable<T> interface, you can do this:



            class GenericQuestion<T extends Number> implements MyIterable<T> {
            List<? extends T> numbers;

            GenericQuestion(List<? extends T> number) {
            this.numbers = number;
            }

            public Iterator<? extends T> iterator() {
            return numbers.iterator();
            }

            static void main() {
            GenericQuestion<Number> q = new GenericQuestion<>(new ArrayList<Integer>());
            Iterator<? extends Number> iter = q.iterator();
            System.out.println(iter.next().byteValue());
            }
            }

            interface MyIterable<T> {
            Iterator<? extends T> iterator();
            }


            But as you can see, you can't use MyIterable with a for loop.



            Therefore, you either don't allow new GenericQuestion<Number>(new ArrayList<Integer>()), or you write type unsafe code.






            share|improve this answer
























            • I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

              – m35
              Jan 28 at 4:18
















            1














            I think you must have some type unsafe code somewhere if you want variance on T.



            The thing that causes this limitation is Iterable<T>. It requires a method Iterator<T> iterator(). You can't be certain that your Iterator<? extends T> can be converted to Iterator<T> because the only case in which this is possible is when your Iterator<? extends T> is a Iterator<T> at runtime. You probably already understand the fact that A<T> cannot be converted to A<U> even if T extends U.



            If instead you created your own MyIterable<T> interface, you can do this:



            class GenericQuestion<T extends Number> implements MyIterable<T> {
            List<? extends T> numbers;

            GenericQuestion(List<? extends T> number) {
            this.numbers = number;
            }

            public Iterator<? extends T> iterator() {
            return numbers.iterator();
            }

            static void main() {
            GenericQuestion<Number> q = new GenericQuestion<>(new ArrayList<Integer>());
            Iterator<? extends Number> iter = q.iterator();
            System.out.println(iter.next().byteValue());
            }
            }

            interface MyIterable<T> {
            Iterator<? extends T> iterator();
            }


            But as you can see, you can't use MyIterable with a for loop.



            Therefore, you either don't allow new GenericQuestion<Number>(new ArrayList<Integer>()), or you write type unsafe code.






            share|improve this answer
























            • I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

              – m35
              Jan 28 at 4:18














            1












            1








            1







            I think you must have some type unsafe code somewhere if you want variance on T.



            The thing that causes this limitation is Iterable<T>. It requires a method Iterator<T> iterator(). You can't be certain that your Iterator<? extends T> can be converted to Iterator<T> because the only case in which this is possible is when your Iterator<? extends T> is a Iterator<T> at runtime. You probably already understand the fact that A<T> cannot be converted to A<U> even if T extends U.



            If instead you created your own MyIterable<T> interface, you can do this:



            class GenericQuestion<T extends Number> implements MyIterable<T> {
            List<? extends T> numbers;

            GenericQuestion(List<? extends T> number) {
            this.numbers = number;
            }

            public Iterator<? extends T> iterator() {
            return numbers.iterator();
            }

            static void main() {
            GenericQuestion<Number> q = new GenericQuestion<>(new ArrayList<Integer>());
            Iterator<? extends Number> iter = q.iterator();
            System.out.println(iter.next().byteValue());
            }
            }

            interface MyIterable<T> {
            Iterator<? extends T> iterator();
            }


            But as you can see, you can't use MyIterable with a for loop.



            Therefore, you either don't allow new GenericQuestion<Number>(new ArrayList<Integer>()), or you write type unsafe code.






            share|improve this answer













            I think you must have some type unsafe code somewhere if you want variance on T.



            The thing that causes this limitation is Iterable<T>. It requires a method Iterator<T> iterator(). You can't be certain that your Iterator<? extends T> can be converted to Iterator<T> because the only case in which this is possible is when your Iterator<? extends T> is a Iterator<T> at runtime. You probably already understand the fact that A<T> cannot be converted to A<U> even if T extends U.



            If instead you created your own MyIterable<T> interface, you can do this:



            class GenericQuestion<T extends Number> implements MyIterable<T> {
            List<? extends T> numbers;

            GenericQuestion(List<? extends T> number) {
            this.numbers = number;
            }

            public Iterator<? extends T> iterator() {
            return numbers.iterator();
            }

            static void main() {
            GenericQuestion<Number> q = new GenericQuestion<>(new ArrayList<Integer>());
            Iterator<? extends Number> iter = q.iterator();
            System.out.println(iter.next().byteValue());
            }
            }

            interface MyIterable<T> {
            Iterator<? extends T> iterator();
            }


            But as you can see, you can't use MyIterable with a for loop.



            Therefore, you either don't allow new GenericQuestion<Number>(new ArrayList<Integer>()), or you write type unsafe code.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 18 '18 at 9:28









            SweeperSweeper

            67k1073139




            67k1073139













            • I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

              – m35
              Jan 28 at 4:18



















            • I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

              – m35
              Jan 28 at 4:18

















            I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

            – m35
            Jan 28 at 4:18





            I did end up going the simple, though technically type unsafe approach return (Iterator<T>)numbers.iterator();

            – m35
            Jan 28 at 4:18













            1














            A litle change to your test so that it is not trying to force to GenericQuestion<Number> (but to let infer type instead):



            for (Number n : new GenericQuestion<>(new ArrayList<Integer>())) {


            Also you could change the declaration for the List type of iterable, like:



            class GenericQuestion<T extends Number, L extends List<T>>
            implements Iterable<T> {

            private L numbers;

            GenericQuestion(L number) {
            this.numbers = number;
            }





            share|improve this answer


























            • I removed code to keep the question simple. A list is required in the full implementation.

              – m35
              Nov 18 '18 at 9:21











            • Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

              – m35
              Jan 28 at 4:21
















            1














            A litle change to your test so that it is not trying to force to GenericQuestion<Number> (but to let infer type instead):



            for (Number n : new GenericQuestion<>(new ArrayList<Integer>())) {


            Also you could change the declaration for the List type of iterable, like:



            class GenericQuestion<T extends Number, L extends List<T>>
            implements Iterable<T> {

            private L numbers;

            GenericQuestion(L number) {
            this.numbers = number;
            }





            share|improve this answer


























            • I removed code to keep the question simple. A list is required in the full implementation.

              – m35
              Nov 18 '18 at 9:21











            • Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

              – m35
              Jan 28 at 4:21














            1












            1








            1







            A litle change to your test so that it is not trying to force to GenericQuestion<Number> (but to let infer type instead):



            for (Number n : new GenericQuestion<>(new ArrayList<Integer>())) {


            Also you could change the declaration for the List type of iterable, like:



            class GenericQuestion<T extends Number, L extends List<T>>
            implements Iterable<T> {

            private L numbers;

            GenericQuestion(L number) {
            this.numbers = number;
            }





            share|improve this answer















            A litle change to your test so that it is not trying to force to GenericQuestion<Number> (but to let infer type instead):



            for (Number n : new GenericQuestion<>(new ArrayList<Integer>())) {


            Also you could change the declaration for the List type of iterable, like:



            class GenericQuestion<T extends Number, L extends List<T>>
            implements Iterable<T> {

            private L numbers;

            GenericQuestion(L number) {
            this.numbers = number;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 18 '18 at 9:29

























            answered Nov 18 '18 at 9:11









            pirhopirho

            4,370101830




            4,370101830













            • I removed code to keep the question simple. A list is required in the full implementation.

              – m35
              Nov 18 '18 at 9:21











            • Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

              – m35
              Jan 28 at 4:21



















            • I removed code to keep the question simple. A list is required in the full implementation.

              – m35
              Nov 18 '18 at 9:21











            • Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

              – m35
              Jan 28 at 4:21

















            I removed code to keep the question simple. A list is required in the full implementation.

            – m35
            Nov 18 '18 at 9:21





            I removed code to keep the question simple. A list is required in the full implementation.

            – m35
            Nov 18 '18 at 9:21













            Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

            – m35
            Jan 28 at 4:21





            Using GenericQuestion<T extends Number, L extends List<T>> does appear to be an option, though it requires all users of this class to declare that additional generic argument.

            – m35
            Jan 28 at 4:21











            0














            Another solution I found was to wrap the wildcard iterator with an iterator of the base type. I suspect this is technically how you're supposed to handle this situation.



            class GenericQuestion<T extends Number> implements Iterable<T> {
            List<? extends T> numbers;

            GenericQuestion(List<? extends T> number) {
            this.numbers = number;
            }

            public Iterator<T> iterator() {
            return new Iterator<T>() {
            Iterator<? extends T> iter = numbers.iterator();
            public boolean hasNext() {
            return iter.hasNext();
            }

            public T next() {
            return iter.next();
            }

            public void remove() {
            iter.remove();
            }
            };
            }

            static void main() {
            for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
            System.out.println(n.byteValue());
            }
            }
            }





            share|improve this answer




























              0














              Another solution I found was to wrap the wildcard iterator with an iterator of the base type. I suspect this is technically how you're supposed to handle this situation.



              class GenericQuestion<T extends Number> implements Iterable<T> {
              List<? extends T> numbers;

              GenericQuestion(List<? extends T> number) {
              this.numbers = number;
              }

              public Iterator<T> iterator() {
              return new Iterator<T>() {
              Iterator<? extends T> iter = numbers.iterator();
              public boolean hasNext() {
              return iter.hasNext();
              }

              public T next() {
              return iter.next();
              }

              public void remove() {
              iter.remove();
              }
              };
              }

              static void main() {
              for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
              System.out.println(n.byteValue());
              }
              }
              }





              share|improve this answer


























                0












                0








                0







                Another solution I found was to wrap the wildcard iterator with an iterator of the base type. I suspect this is technically how you're supposed to handle this situation.



                class GenericQuestion<T extends Number> implements Iterable<T> {
                List<? extends T> numbers;

                GenericQuestion(List<? extends T> number) {
                this.numbers = number;
                }

                public Iterator<T> iterator() {
                return new Iterator<T>() {
                Iterator<? extends T> iter = numbers.iterator();
                public boolean hasNext() {
                return iter.hasNext();
                }

                public T next() {
                return iter.next();
                }

                public void remove() {
                iter.remove();
                }
                };
                }

                static void main() {
                for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
                System.out.println(n.byteValue());
                }
                }
                }





                share|improve this answer













                Another solution I found was to wrap the wildcard iterator with an iterator of the base type. I suspect this is technically how you're supposed to handle this situation.



                class GenericQuestion<T extends Number> implements Iterable<T> {
                List<? extends T> numbers;

                GenericQuestion(List<? extends T> number) {
                this.numbers = number;
                }

                public Iterator<T> iterator() {
                return new Iterator<T>() {
                Iterator<? extends T> iter = numbers.iterator();
                public boolean hasNext() {
                return iter.hasNext();
                }

                public T next() {
                return iter.next();
                }

                public void remove() {
                iter.remove();
                }
                };
                }

                static void main() {
                for (Number n : new GenericQuestion<Number>(new ArrayList<Integer>())) {
                System.out.println(n.byteValue());
                }
                }
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 19 at 14:11









                m35m35

                10528




                10528






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53359229%2frectifying-an-upper-bounded-class-type-iterable-and-upper-bounded-wildcard-list%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Academy of Television Arts & Sciences

                    L'Équipe

                    1995 France bombings