Dynamic method calls

Discussion in 'Java' started by Denis Palas, Dec 21, 2006.

  1. Denis Palas

    Denis Palas Guest

    Dear All

    I am trying to use dynamic method calls, and have written the below code,
    but not getting any results. Could you please help to point out my mistakes?

    Thank you in advance
    Denis

    // ------------------------------------- My code -------------------------
    import java.lang.reflect.*;
    import java.text.*;
    import java.util.*;


    public class TestClass {

    public static void main(String[] args) throws Exception {

    TestClass cartrec = new TestClass();
    cartrec.solvethis();
    } // End main


    public void solvethis () {

    Object myres=0 ;


    String Functionstest[][]= {
    {"Mult1","1","2","3"},
    {"Concat1","Good","morning"},
    {"Date1Before","7 7 2004","8 8 2005"}
    };


    // To invoke the Mult1 method
    //---------------------------------------------------------------
    Class c = this.getClass();

    Class[] parameterTypes = new Class[Functionstest[0].length];
    Object[] parameters = new Object[Functionstest[0].length];

    try {

    for (int j = 0; j < Functionstest[0].length - 1; j++) {
    parameterTypes[j] = Integer.TYPE;
    parameters[j] = new Integer(Functionstest[0][j+1]);
    }


    Method m = c.getMethod(Functionstest[0][0], parameterTypes);
    myres = m.invoke(this, parameters);


    } // End Try

    catch (IllegalAccessException e) { }
    catch (InvocationTargetException e) { }
    catch (NoSuchMethodException e) { }

    System.out.println("The result is = " + myres);

    } // end solve this

    // -----------------------------------------------------------------------
    public int Mult1(int Var1,int Var2, int Var3)

    {
    int result;

    result= Var1 * Var2 * Var3;
    return result;
    }
     
    Denis Palas, Dec 21, 2006
    #1
    1. Advertising

  2. Denis Palas

    Lew Guest

    Denis Palas wrote:
    > Dear All
    >
    > I am trying to use dynamic method calls, and have written the below code,
    > but not getting any results. Could you please help to point out my mistakes?
    >
    > Thank you in advance
    > Denis
    >
    > // ------------------------------------- My code -------------------------


    First, fix any compilation errors.

    > import java.lang.reflect.*;


    Assiduously avoid use of reflection.

    > import java.text.*;
    > import java.util.*;
    >
    >
    > public class TestClass {
    >
    > public static void main(String[] args) throws Exception {


    You should indent code (using spaces, not TABs) that you post, to enhance
    readability.

    ....

    > Object myres=0 ;


    This only works in Java 5 +. You might have made the intent clearer by
    declaring the variable as Integer.

    Why the throwaway initialization anyway?

    > String Functionstest[][]= {


    Java programming convention is that variable and method names begin with a
    lower-case letter, and that each subsequent "word" component begin with an
    upper-case letter: "functionsTest'.

    > {"Mult1","1","2","3"},

    ....

    > for (int j = 0; j < Functionstest[0].length - 1; j++) {
    > parameterTypes[j] = Integer.TYPE;


    So "Mult1" is a parameter of Integer.TYPE.

    > parameters[j] = new Integer(Functionstest[0][j+1]);
    > }
    >
    >
    > Method m = c.getMethod(Functionstest[0][0], parameterTypes);


    You've already declared "Functionstest[0][0]" to be an Integer.TYPE parameter,
    despite that its value does not parse to an integer. It should not also be a
    method name.

    > myres = m.invoke(this, parameters);


    Kaboom!

    > } // End Try
    >
    > catch (IllegalAccessException e) { }
    > catch (InvocationTargetException e) { }
    > catch (NoSuchMethodException e) { }


    You should not ignore Exceptions. The error messages probably would have led
    you to a solution by now.

    > System.out.println("The result is = " + myres);


    "myRes".

    If this is an exercise to learn reflection, it's useful. Otherwise there are
    better ways to accomplish the task.

    - Lew
     
    Lew, Dec 21, 2006
    #2
    1. Advertising

  3. Denis Palas

    Lew Guest

    >> String Functionstest[][]= {
    >> {"Mult1","1","2","3"},

    ...
    >> for (int j = 0; j < Functionstest[0].length - 1; j++) {
    >> parameterTypes[j] = Integer.TYPE;


    > So "Mult1" is a parameter of Integer.TYPE.


    >> parameters[j] = new Integer(Functionstest[0][j+1]);
    >> }
    >>
    >>
    >> Method m = c.getMethod(Functionstest[0][0], parameterTypes);


    Oops. I just noticed the mismatch in the "j" vs. "j+1" indexes.

    - Lew
     
    Lew, Dec 21, 2006
    #3
  4. Denis Palas wrote:
    > Dear All
    >
    > I am trying to use dynamic method calls, and have written the below code,
    > but not getting any results. Could you please help to point out my mistakes?
    >
    > Thank you in advance
    > Denis
    >
    > // ------------------------------------- My code -------------------------
    > import java.lang.reflect.*;
    > import java.text.*;
    > import java.util.*;
    >
    >
    > public class TestClass {
    >
    > public static void main(String[] args) throws Exception {
    >
    > TestClass cartrec = new TestClass();
    > cartrec.solvethis();
    > } // End main
    >
    >
    > public void solvethis () {
    >
    > Object myres=0 ;
    >
    >
    > String Functionstest[][]= {
    > {"Mult1","1","2","3"},
    > {"Concat1","Good","morning"},
    > {"Date1Before","7 7 2004","8 8 2005"}
    > };
    >
    >
    > // To invoke the Mult1 method
    > //---------------------------------------------------------------
    > Class c = this.getClass();
    >
    > Class[] parameterTypes = new Class[Functionstest[0].length];
    > Object[] parameters = new Object[Functionstest[0].length];
    >
    > try {
    >
    > for (int j = 0; j < Functionstest[0].length - 1; j++) {
    > parameterTypes[j] = Integer.TYPE;
    > parameters[j] = new Integer(Functionstest[0][j+1]);
    > }
    >
    >
    > Method m = c.getMethod(Functionstest[0][0], parameterTypes);
    > myres = m.invoke(this, parameters);
    >
    >
    > } // End Try
    >
    > catch (IllegalAccessException e) { }
    > catch (InvocationTargetException e) { }
    > catch (NoSuchMethodException e) { }
    >
    > System.out.println("The result is = " + myres);
    >
    > } // end solve this
    >
    > // -----------------------------------------------------------------------
    > public int Mult1(int Var1,int Var2, int Var3)
    >
    > {
    > int result;
    >
    > result= Var1 * Var2 * Var3;
    > return result;
    > }


    I don't know what's wrong here, but I do have some advice: don't use
    reflection, unless you really, really, really need to low-level-hack
    code that isn't known until runtime, which tends to be only if you're
    writing code-grokking tools like debuggers or profilers or coverage
    tools or automated testing systems that use reflection and annotations
    to save people the bother of writing separate unit test classes or whatever.

    Most often, when you want to call a method that is determined
    dynamically at run-time, or reflectively inspect and change the
    properties of an object, what you want is a) polymorphism and b) a class
    with built-in support for programmatic property discovery and
    manipulation. And then you want to use interfaces.

    In the case of invoking the method of some user's choice at runtime, you
    use code like this:

    public void myMethod (FooDoer f, other args) {
    ...
    f.doFoo(args)
    ...
    }

    and write an interface like this:

    /**
    * Explain what this interface is for
    */
    public interface FooDoer {
    /**
    * Explain what this should do and who calls it when and why
    */
    public void doFoo (args);
    }

    Now the callers of your code can supply their own FooDoer implementation
    and their own version of the doFoo method gets called by your code in
    myMethod.

    For the property-inspectable thing you expand on this theme:

    public interface PropertyInspectable extends Serializable, Cloneable {
    public Set<String> getPropertyNames();
    public Object getProperty (String name)
    throws PropertyException;
    public void setProperty (String name, Object value)
    throws PropertyException;
    }

    public class PropertyException extends Exception ...

    and create things like PropertyParseException, NoSuchPropertyException,
    and so forth for the latter two to throw as needed. Users of your code
    can do things like getPropertyNames() on your PropertyInspectables to
    discover property names, and getProperty(name) to get particular
    properties. Ones with their own nested properties can be found with

    Object o = foo.getProperty(name);
    if (o instanceof PropertyInspectable) doSomething((PropertyInspectable)o);

    and the rest might be assumed to be a mix of Strings and one of a few
    boxed-primitive types like Integer and Double, maybe also BigInteger and
    BigDecimal. And, of course, you can expand on that notion and throw in a
    whole meta-level scripting interface in a "public interface Scriptable"
    or whatever, or extract o.getClass() and do something with that ...

    Or, of course,

    public interface DirectlyUserEditable {
    public JFrame getViewerInstance();
    public JFrame getEditorInstance();
    }

    public class MyFoobar implements DirectlyUserEditable {
    private int ivar1;

    public JFrame getViewerInstance () {
    return new Editor(true);
    }
    public JFrame getEditorInstance () {
    return new Editor(false);
    }
    public class Editor extends JFrame ...
    ...
    ... public Editor (boolean readOnly) { ...
    ...
    ... ivar1 = Integer.valueOf(area.getText()) ...
    ...
    }

    :)
     
    John Ersatznom, Dec 21, 2006
    #4
  5. Denis Palas

    Denis Palas Guest

    Thank you for your reply ...


    "Lew" <> wrote in message
    news:...
    >>> String Functionstest[][]= {
    >>> {"Mult1","1","2","3"},

    > ...
    >>> for (int j = 0; j < Functionstest[0].length - 1; j++) {
    >>> parameterTypes[j] = Integer.TYPE;

    >
    >> So "Mult1" is a parameter of Integer.TYPE.

    >
    >>> parameters[j] = new Integer(Functionstest[0][j+1]);
    >>> }
    >>>
    >>>
    >>> Method m = c.getMethod(Functionstest[0][0], parameterTypes);

    >
    > Oops. I just noticed the mismatch in the "j" vs. "j+1" indexes.
    >
    > - Lew
     
    Denis Palas, Dec 22, 2006
    #5
  6. Denis Palas

    Alfred Guest

    John Ersatznom wrote:
    > Denis Palas wrote:
    >
    > [Reflection problems]
    >
    > I don't know what's wrong here, but I do have some advice: don't use
    > reflection, unless you really, really, really need to low-level-hack
    > code that isn't known until runtime, which tends to be only if you're
    > writing code-grokking tools like debuggers or profilers or coverage
    > tools or automated testing systems that use reflection and annotations
    > to save people the bother of writing separate unit test classes or
    > whatever.
    >
    > [a lot of useless stuff]


    How do implement a Class Analyzer? You don't know
    what's wrong, you dont't know enough about Reflection
    but you want to know what the OP want to do...

    Alfred
     
    Alfred, Dec 22, 2006
    #6
    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. Honne Gowda A
    Replies:
    2
    Views:
    913
    Karl Heinz Buchegger
    Oct 31, 2003
  2. andy6
    Replies:
    2
    Views:
    793
    andy6 via DotNetMonster.com
    Jun 9, 2006
  3. Richard Tobin
    Replies:
    24
    Views:
    825
  4. x1
    Replies:
    2
    Views:
    210
  5. Matt Mencel

    Dynamic Method Calls

    Matt Mencel, Apr 1, 2010, in forum: Ruby
    Replies:
    3
    Views:
    159
    Ryan Davis
    Apr 1, 2010
Loading...

Share This Page