How would you invoke arrayList.get() through reflection in 1.4 ??

Discussion in 'Java' started by Sébastien de Mapias, Nov 5, 2009.

  1. Hi,

    It seems to be pretty hard to invoke the List get(int) method through
    reflection. I didn't manage to have my code working with my 1.4
    compiler.
    To sum up I do the following:

    Method method;
    method = [some more code...];
    if (method.getReturnType().toString().equals("interface
    java.util.List"))
    {

    // how many refs does our List contain ?
    int n = sizeOfCollection(method.invoke(root, (Object[])null));

    // let's get the actual list
    Object list = method.invoke(root, (Object[])null);

    // now trying to invoke its 'get()' for every element it
    // contains:
    Class listClass = Class.forName(list.getClass().getName());
    Method m2 = listClass.getDeclaredMethod("get", ???); //<= what to
    put here ?

    for (int i=0; i<n; i++) {
    Object o = m2.invoke(list, i); //<= doesn't compile
    ...
    }
    [...]
    }

    private int sizeOfCollection(Object obj)
    {
    return new StringTokenizer(obj.toString(), ",").countTokens();
    }

    In Java5 I managed to reach a point where I could traverse
    all references contained in a List, and display them, but in 1.4,
    no way: if someone every succeeded doing that, I'd be glad to
    hear how you did it... Thanks a lot in advance !

    Regards,
    Seb
     
    Sébastien de Mapias, Nov 5, 2009
    #1
    1. Advertising

  2. Sébastien de Mapias

    markspace Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    Sébastien de Mapias wrote:
    > Hi,
    >
    > It seems to be pretty hard to invoke the List get(int) method through
    > reflection. I didn't manage to have my code working with my 1.4
    > compiler.


    It isn't. Your code is pretty bad. I'll make some more comments about
    that in a sec, you're making things way harder than need to be. First,
    a direct answer to your question:

    Method m = obj.getClass().getMethod( "get", Integer.TYPE );

    Likely you have "Integer.class" or similar, you have to use the type for
    a primitive, not the object Integer.

    Ok, on to comments.


    > To sum up I do the following:
    >
    > Method method;
    > method = [some more code...];
    > if (method.getReturnType().toString().equals("interface
    > java.util.List"))



    That line above drives me nuts. Why do a string compare? Why not just
    compare to the class itself?


    > if (method.getReturnType() == List.class )



    Not sure what the confusion is with that.


    > {
    >
    > // how many refs does our List contain ?
    > int n = sizeOfCollection(method.invoke(root, (Object[])null));



    That line is a terrible idea. More later.


    >
    > // let's get the actual list
    > Object list = method.invoke(root, (Object[])null);



    At this point you could just cast to a list, you know. This is the
    biggest "wtf?" in your code for me.

    List<?> list = (List) obj;
    for( Object o : list ) {
    System.out.println( o );
    }

    There's your "reflective" way to get all members of the list from an Object.


    >
    > // now trying to invoke its 'get()' for every element it
    > // contains:
    > Class listClass = Class.forName(list.getClass().getName());
    > Method m2 = listClass.getDeclaredMethod("get", ???); //<= what to
    > put here ?


    See above.

    >
    > for (int i=0; i<n; i++) {
    > Object o = m2.invoke(list, i); //<= doesn't compile
    > ...
    > }


    Ditto.

    > [...]
    > }
    >
    > private int sizeOfCollection(Object obj)
    > {
    > return new StringTokenizer(obj.toString(), ",").countTokens();
    > }


    A close second place for "wtf?". Please. What if your string(s)
    contain commas themselves? This can't work in the general case. Bad
    bad code, bad idea. Just cast to a list and then call the normal
    methods, like ".size()".



    Here's my reflective example:

    package oldlist;

    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.List;


    public class Main {
    public static void main(String[] args) throws NoSuchMethodException
    {
    Object x = Arrays.asList( "red", "fish", "blue", "fish" );
    reflectList( x );
    }

    private static void reflectList( Object obj )
    throws NoSuchMethodException
    {
    if( obj instanceof List ) {
    List<?> list = (List) obj;
    for( Object o : list ) {
    System.out.println( o );
    }
    }
    Method m = obj.getClass().getMethod( "get", Integer.TYPE );
    System.out.println( m );
    }
    }
     
    markspace, Nov 5, 2009
    #2
    1. Advertising

  3. markspace wrote:
    > Sébastien de Mapias wrote:
    >> Hi,
    >>
    >> It seems to be pretty hard to invoke the List get(int) method
    >> through
    >> reflection. I didn't manage to have my code working with my 1.4
    >> compiler.

    >
    > It isn't. Your code is pretty bad. I'll make some more comments
    > about that in a sec, you're making things way harder than need to
    > be.
    > First, a direct answer to your question:
    >
    > Method m = obj.getClass().getMethod( "get", Integer.TYPE );


    I was going to correct you, but checked first and saw that getMethod()
    is now declared as varargs. Very handy.
     
    Mike Schilling, Nov 5, 2009
    #3
  4. Sébastien de Mapias

    markspace Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    Mike Schilling wrote:

    > markspace wrote:
    >> First, a direct answer to your question:
    >>
    >> Method m = obj.getClass().getMethod( "get", Integer.TYPE );

    >
    > I was going to correct you, but checked first and saw that getMethod()
    > is now declared as varargs. Very handy.



    Ah ha.... I had set my compiler flags to -source 1.4 -target 1.4, but
    apparently there's still a few sneaky things that don't get checked
    directly. I didn't look at the 1.4 docs closely enough, I suppose.

    Method m=obj.getClass().getMethod("get",new Class[]{Integer.TYPE});

    Seems to work for me also, and I suspect will work on an older compiler
    as well.
     
    markspace, Nov 5, 2009
    #4
  5. Sébastien de Mapias

    Lew Guest

    Sébastien de Mapias wrote:
    >>> ... working with my 1.4 compiler.

    >


    markspace wrote:
    >> First, a direct answer to your question:

    >
    >>    Method m = obj.getClass().getMethod( "get", Integer.TYPE );

    >


    Mike Schilling wrote:
    > I was going to correct you, but checked first and saw that getMethod()
    > is now declared as varargs.  Very handy.
    >


    The varargs feature wasn't introduced until Java 5. Go ahead and
    correct him.

    --
    Lew
     
    Lew, Nov 5, 2009
    #5
  6. Sébastien de Mapias

    MikisM Guest

    >            List<?> list = (List) obj;
    >            for( Object o : list ) {
    >               System.out.println( o );
    >            }
    >         }


    I'm not 100% sure but weren't generics (<?> in this case) included in
    1.5 version? The code should not compile with 1.4.
     
    MikisM, Nov 6, 2009
    #6
  7. Sébastien de Mapias

    markspace Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    MikisM wrote:
    >> List<?> list = (List) obj;
    >> for( Object o : list ) {
    >> System.out.println( o );
    >> }
    >> }

    >
    > I'm not 100% sure but weren't generics (<?> in this case) included in
    > 1.5 version? The code should not compile with 1.4.



    Yup, and that for:)) loop doesn't work either under 1.4. I put -source
    1.4 on the compile line for javac, but it didn't work. Up further in
    the same dialog there's a sources tab, with a drop down for the source
    revision. Setting it there works. This is using Netbeans, under the
    project Properties.

    Thanks for provoking me into figuring this out.
     
    markspace, Nov 6, 2009
    #7
  8. Sébastien de Mapias

    Daniel Pitts Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    Sébastien de Mapias wrote:
    > Hi,
    >
    > It seems to be pretty hard to invoke the List get(int) method through
    > reflection. I didn't manage to have my code working with my 1.4
    > compiler.

    Why? Why not use ((List)obj).get(i);
    That is *much* easier than using reflection.

    > To sum up I do the following:
    >
    > Method method;
    > method = [some more code...];
    > if (method.getReturnType().toString().equals("interface
    > java.util.List"))
    > {
    >
    > // how many refs does our List contain ?
    > int n = sizeOfCollection(method.invoke(root, (Object[])null));
    >
    > // let's get the actual list
    > Object list = method.invoke(root, (Object[])null);
    >
    > // now trying to invoke its 'get()' for every element it
    > // contains:
    > Class listClass = Class.forName(list.getClass().getName());
    > Method m2 = listClass.getDeclaredMethod("get", ???); //<= what to
    > put here ?
    >
    > for (int i=0; i<n; i++) {
    > Object o = m2.invoke(list, i); //<= doesn't compile
    > ...
    > }
    > [...]
    > }
    >
    > private int sizeOfCollection(Object obj)
    > {
    > return new StringTokenizer(obj.toString(), ",").countTokens();
    > }
    >
    > In Java5 I managed to reach a point where I could traverse
    > all references contained in a List, and display them, but in 1.4,
    > no way: if someone every succeeded doing that, I'd be glad to
    > hear how you did it... Thanks a lot in advance !
    >
    > Regards,
    > Seb
     
    Daniel Pitts, Nov 6, 2009
    #8
  9. Sébastien de Mapias

    Lew Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    markspace wrote:
    > MikisM wrote:
    >>> List<?> list = (List) obj;
    >>> for( Object o : list ) {
    >>> System.out.println( o );
    >>> }
    >>> }

    >>
    >> I'm not 100% sure but weren't generics (<?> in this case) included in
    >> 1.5 version? The code should not compile with 1.4.

    >
    >
    > Yup, and that for:)) loop doesn't work either under 1.4. I put -source
    > 1.4 on the compile line for javac, but it didn't work. Up further in
    > the same dialog there's a sources tab, with a drop down for the source
    > revision. Setting it there works. This is using Netbeans, under the
    > project Properties.
    >
    > Thanks for provoking me into figuring this out.


    you probably also needed "-target 1.4" and perhaps even
    "-bootclasspath $JDK14/rt.jar"

    --
    Lew
     
    Lew, Nov 7, 2009
    #9
  10. Sébastien de Mapias

    markspace Guest

    Re: How would you invoke arrayList.get() through reflection in 1.4??

    Lew wrote:

    >
    > you probably also needed "-target 1.4" and perhaps even


    I had that, it didn't seem to work either.

    Under Properties -> Libraries, there's a "Java Platform" drop down menu.
    I don't have Java 1.4 installed, so I can't check, but I'm going to
    guess that switching that menu will enable NetBeans to use a different
    JDK and also set the -target flag correctly.


    > "-bootclasspath $JDK14/rt.jar"
    >
     
    markspace, Nov 7, 2009
    #10
  11. In article <hd2j1t$sfj$-september.org>,
    markspace <> wrote:

    > Lew wrote:
    >
    > >
    > > you probably also needed "-target 1.4" and perhaps even

    >
    > I had that, it didn't seem to work either.
    >
    > Under Properties -> Libraries, there's a "Java Platform" drop down menu.
    > I don't have Java 1.4 installed, so I can't check, but I'm going to
    > guess that switching that menu will enable NetBeans to use a different
    > JDK and also set the -target flag correctly.


    I was similarly stymied for a time in NetBeans 6.5. On my machine, Java
    1.5 is the default; I had to add 1.4.2 and 1.6 in the Tools -> Java
    Platforms dialog. Even after making 1.6 available, I couldn't change
    Properties -> Source/Binary Format to JDK 6 until I first set Properties
    -> Libraries -> Java Platform to JDK 1.6.

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
     
    John B. Matthews, Nov 7, 2009
    #11
  12. Sébastien de Mapias

    Roedy Green Guest

    On Thu, 5 Nov 2009 06:47:16 -0800 (PST), Sébastien de Mapias
    <> wrote, quoted or indirectly quoted someone who
    said :

    >if (method.getReturnType().toString().equals("interface
    >java.util.List"))

    if you know at compile time you are looking for a java.util.List
    interface object, you don't need reflection or anything fancy. Just
    do a Class.forName and cast to a (List) or use generics to cast it for
    you. You can then use a List ref to access all the methods of List
    in a straightforward way.

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    Without deviation from the norm, progress is not possible.
    ~ Frank Zappa (born: 1940-12-21 died: 1993-12-04 at age: 52)
     
    Roedy Green, Nov 9, 2009
    #12
    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. [Gauthier]
    Replies:
    2
    Views:
    14,206
    [Gauthier]
    Dec 3, 2003
  2. jerry051
    Replies:
    2
    Views:
    773
    Oliver Sturm
    Aug 2, 2005
  3. Saravanan Rathinavelu

    Iterate through ArrayList using an another ArrayList

    Saravanan Rathinavelu, Aug 16, 2003, in forum: ASP .Net
    Replies:
    3
    Views:
    2,771
    Natty Gur
    Aug 19, 2003
  4. Daniel
    Replies:
    0
    Views:
    438
    Daniel
    Mar 12, 2005
  5. Sébastien de Mapias
    Replies:
    11
    Views:
    2,783
    Sébastien de Mapias
    Sep 23, 2008
Loading...

Share This Page