Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2006

Tip: Looking for answers? Try searching our database.

Dynamic method calls

Thread view: 
Denis Palas - 21 Dec 2006 15:56 GMT
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;
}
Lew - 21 Dec 2006 17:02 GMT
> Dear  All
>
[quoted text clipped - 5 lines]
>
> // ------------------------------------- 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 - 21 Dec 2006 17:09 GMT
>> 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 - 22 Dec 2006 04:40 GMT
Thank you for your reply ...

>>> String Functionstest[][]= {
>>>                     {"Mult1","1","2","3"},
[quoted text clipped - 12 lines]
>
> - Lew
John Ersatznom - 21 Dec 2006 17:32 GMT
> Dear  All
>
[quoted text clipped - 63 lines]
> 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()) ...
    ...
}

:)
Alfred - 22 Dec 2006 17:13 GMT
> [Reflection problems]
>
[quoted text clipped - 7 lines]
>
> [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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.