limitations of generic reflection

Discussion in 'Java' started by Roger Levy, Apr 16, 2008.

  1. Roger Levy

    Roger Levy Guest

    I think I have hit up against an interesting limitation of generics in
    Java, and I want to confirm that I'm understanding the limitations
    properly. I would like to write a method that takes a parameterized
    Collection of type C<A>, and apply to each member of the Collection a
    method that takes an A and returns a B. The result should be a
    Collection of type C<B>. The code would ideally look something like:

    public <A, B, C extends Collection> C<B> applyAll(C<A> as,
    Function<A,B> f) {
    C<B> result = (C<B>) as.getClass().newInstance();
    for(A a : as)
    result.add(f.apply(a));
    return result;
    }

    with the appropriate exception handling. But it seems like this is
    impossible because type parameters themselves cannot be
    parameterized. Is there a way around this limitation that I haven't
    thought of?

    Many thanks!

    Roger
    Roger Levy, Apr 16, 2008
    #1
    1. Advertising

  2. On Apr 16, 12:58 pm, Roger Levy <> wrote:
    > I think I have hit up against an interesting limitation of generics in
    > Java, and I want to confirm that I'm understanding the limitations
    > properly.  I would like to write a method that takes a parameterized
    > Collection of type C<A>, and apply to each member of the Collection a
    > method that takes an A and returns a B.  The result should be a
    > Collection of type C<B>.  The code would ideally look something like:
    >
    >   public <A, B, C extends Collection> C<B> applyAll(C<A> as,
    > Function<A,B> f) {
    >     C<B> result = (C<B>) as.getClass().newInstance();
    >     for(A a : as)
    >       result.add(f.apply(a));
    >     return result;
    >   }
    >
    > with the appropriate exception handling.  But it seems like this is
    > impossible because type parameters themselves cannot be
    > parameterized.  Is there a way around this limitation that I haven't
    > thought of?


    You can parameterize type bounds:

    public static
    <A, B,
    CA extends Collection<A>,
    CB extends Collection<B>>
    CB apply(
    CA as, Function<A, B> f) {

    }

    however, once you're past that hurdle, you're going to discover that
    you can't, eg., do 'new CB', which you'd need for a truly generic
    implementation of the map meta-function, nor can you specialize
    generics on some arguments the way you could with C++ templates.

    -o
    Owen Jacobson, Apr 16, 2008
    #2
    1. Advertising

  3. Roger Levy

    Guest

    On Apr 16, 12:08 pm, Owen Jacobson <> wrote:
    > On Apr 16, 12:58 pm, Roger Levy <> wrote:
    >
    >
    >
    > > I think I have hit up against an interesting limitation of generics in
    > > Java, and I want to confirm that I'm understanding the limitations
    > > properly.  I would like to write a method that takes a parameterized
    > > Collection of type C<A>, and apply to each member of the Collection a
    > > method that takes an A and returns a B.  The result should be a
    > > Collection of type C<B>.  The code would ideally look something like:

    >
    > >   public <A, B, C extends Collection> C<B> applyAll(C<A> as,
    > > Function<A,B> f) {
    > >     C<B> result = (C<B>) as.getClass().newInstance();
    > >     for(A a : as)
    > >       result.add(f.apply(a));
    > >     return result;
    > >   }

    >
    > > with the appropriate exception handling.  But it seems like this is
    > > impossible because type parameters themselves cannot be
    > > parameterized.  Is there a way around this limitation that I haven't
    > > thought of?

    >
    > You can parameterize type bounds:
    >
    >     public static
    >       <A, B,
    >        CA extends Collection<A>,
    >        CB extends Collection<B>>
    >       CB apply(
    >             CA as, Function<A, B> f) {
    >
    >     }
    >
    > however, once you're past that hurdle, you're going to discover that
    > you can't, eg., do 'new CB', which you'd need for a truly generic
    > implementation of the map meta-function, nor can you specialize
    > generics on some arguments the way you could with C++ templates.


    This may be a redundant post, but I've found that making the meta-
    function evaluation lazy allow you to "code around" the issue somewhat
    elegantly.

    Assume that your applyAll() returns an Iterable<B> object and computes
    f.apply() on demand. In order to get a collection of type C<B>, you
    have to do a bit more work by creating an addAll() method. The
    framework looks like this (I may be off on exact syntax of the
    wildcard bounds, I hope the intention is clear):

    public static <A, B> Iterable<B> applyAll( Collection<? extends A> as,
    Function<A, B> f ) { // lazy implementation... }

    public static <A> void addAll( Collection<? super A> c, Iterable<?
    extends A> iterable )
    {
    for ( A a : iterable )
    c.add( a );
    }

    In your code you might do the following. Assume Set<A> and List<A>
    are populated with values.

    Function<A, B> myFunc = new MyFunc();
    Set<A> sa;
    Set<B> sb;
    List<A> la;
    List<B> lb;

    addAll( lb, applyAll( la, myFunc ));
    addAll( sb, applyAll( sa, myFunc ));

    Like I said, not quite as elegant as one might like, but serviceable.
    You might be able to pretty it up some more using the parameterized
    type bounds.
    , Apr 16, 2008
    #3
  4. Roger Levy

    Roger Levy Guest

    On Apr 16, 10:08 am, Owen Jacobson <> wrote:
    > On Apr 16, 12:58 pm, Roger Levy <> wrote:
    >
    >
    >
    > > I think I have hit up against an interesting limitation of generics in
    > > Java, and I want to confirm that I'm understanding the limitations
    > > properly. I would like to write a method that takes a parameterized
    > > Collection of type C<A>, and apply to each member of the Collection a
    > > method that takes an A and returns a B. The result should be a
    > > Collection of type C<B>. The code would ideally look something like:

    >
    > > public <A, B, C extends Collection> C<B> applyAll(C<A> as,
    > > Function<A,B> f) {
    > > C<B> result = (C<B>) as.getClass().newInstance();
    > > for(A a : as)
    > > result.add(f.apply(a));
    > > return result;
    > > }

    >
    > > with the appropriate exception handling. But it seems like this is
    > > impossible because type parameters themselves cannot be
    > > parameterized. Is there a way around this limitation that I haven't
    > > thought of?

    >
    > You can parameterize type bounds:
    >
    > public static
    > <A, B,
    > CA extends Collection<A>,
    > CB extends Collection<B>>
    > CB apply(
    > CA as, Function<A, B> f) {
    >
    > }
    >
    > however, once you're past that hurdle, you're going to discover that
    > you can't, eg., do 'new CB', which you'd need for a truly generic
    > implementation of the map meta-function, nor can you specialize
    > generics on some arguments the way you could with C++ templates.


    Yeah, I did know about this -- thanks!
    Roger Levy, Apr 19, 2008
    #4
  5. Roger Levy

    Roger Levy Guest

    On Apr 16, 11:00 am, wrote:
    > On Apr 16, 12:08 pm, Owen Jacobson <> wrote:
    >
    >
    >
    > > On Apr 16, 12:58 pm, Roger Levy <> wrote:

    >
    > > > I think I have hit up against an interesting limitation of generics in
    > > > Java, and I want to confirm that I'm understanding the limitations
    > > > properly. I would like to write a method that takes a parameterized
    > > > Collection of type C<A>, and apply to each member of the Collection a
    > > > method that takes an A and returns a B. The result should be a
    > > > Collection of type C<B>. The code would ideally look something like:

    >
    > > > public <A, B, C extends Collection> C<B> applyAll(C<A> as,
    > > > Function<A,B> f) {
    > > > C<B> result = (C<B>) as.getClass().newInstance();
    > > > for(A a : as)
    > > > result.add(f.apply(a));
    > > > return result;
    > > > }

    >
    > > > with the appropriate exception handling. But it seems like this is
    > > > impossible because type parameters themselves cannot be
    > > > parameterized. Is there a way around this limitation that I haven't
    > > > thought of?

    >
    > > You can parameterize type bounds:

    >
    > > public static
    > > <A, B,
    > > CA extends Collection<A>,
    > > CB extends Collection<B>>
    > > CB apply(
    > > CA as, Function<A, B> f) {

    >
    > > }

    >
    > > however, once you're past that hurdle, you're going to discover that
    > > you can't, eg., do 'new CB', which you'd need for a truly generic
    > > implementation of the map meta-function, nor can you specialize
    > > generics on some arguments the way you could with C++ templates.

    >
    > This may be a redundant post, but I've found that making the meta-
    > function evaluation lazy allow you to "code around" the issue somewhat
    > elegantly.
    >
    > Assume that your applyAll() returns an Iterable<B> object and computes
    > f.apply() on demand. In order to get a collection of type C<B>, you
    > have to do a bit more work by creating an addAll() method. The
    > framework looks like this (I may be off on exact syntax of the
    > wildcard bounds, I hope the intention is clear):
    >
    > public static <A, B> Iterable<B> applyAll( Collection<? extends A> as,
    > Function<A, B> f ) { // lazy implementation... }
    >
    > public static <A> void addAll( Collection<? super A> c, Iterable<?
    > extends A> iterable )
    > {
    > for ( A a : iterable )
    > c.add( a );
    >
    > }
    >
    > In your code you might do the following. Assume Set<A> and List<A>
    > are populated with values.
    >
    > Function<A, B> myFunc = new MyFunc();
    > Set<A> sa;
    > Set<B> sb;
    > List<A> la;
    > List<B> lb;
    >
    > addAll( lb, applyAll( la, myFunc ));
    > addAll( sb, applyAll( sa, myFunc ));
    >
    > Like I said, not quite as elegant as one might like, but serviceable.
    > You might be able to pretty it up some more using the parameterized
    > type bounds.


    Hmm, this is an interesting idea, though it doesn't really get what
    I'd like to have ideally. Oh well...
    Roger Levy, Apr 19, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Saqib Ali

    SOAP:Lite Limitations re: https??

    Saqib Ali, Sep 12, 2003, in forum: Perl
    Replies:
    1
    Views:
    3,021
    Serge Dubrouski
    Sep 16, 2003
  2. Murat Tasan
    Replies:
    1
    Views:
    8,028
    Chaitanya
    Feb 3, 2009
  3. Replies:
    2
    Views:
    424
  4. minlearn
    Replies:
    2
    Views:
    445
    red floyd
    Mar 13, 2009
  5. Replies:
    19
    Views:
    1,872
Loading...

Share This Page