Dynamic method calls

D

Denis Palas

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;
}
 
L

Lew

Denis said:
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
 
L

Lew

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
 
J

John Ersatznom

Denis said:
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()) ...
...
}

:)
 
D

Denis Palas

Thank you for your reply ...


Lew said:
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
 
A

Alfred

John said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top