开发者

How to make method calls dynamically in Java

I'm trying to make a list of function calls. I want to be able to call a specific method by simply choosing the method from an array.

So for example if I want to call, drawCircle() and that method is in the first index than I could say runMethod[0].

Here's what I have so far. I've made an interface with two inputs:

public interface Instruction {  
   void instr( int a, int b );
} 

In my other class I have a list of methods (or should they be classes that implement Instruction?). I want to be able to call any of these methods from a 开发者_JS百科list, like so:

instList[0].mov( 1, 3 );
instList[2].add( 4, 5 );

and so on. Hope that was clear enough. Thanks in advance.


Unless I misunderstand what you're trying to achieve, the regular Java way of doing it is by implementing the interface:

interface Instruction {  
    void instr( int a, int b );
}

class MoveInstruction implements Instruction {
    void instr(int a, int b) {
        // do something
    }
}

class AddInstruction implements Instruction {
    void instr(int a, int b) {
        // do something else
    }
}

And now:

Instruction[] instructions = new Instruction[5];
instructions[0] = new MoveInstruction();
instructions[2] = new AddInstruction();

...

instructions[0].instr(1, 3);
instructions[2].instr(4, 5);

If your only use of the MoveInstruction / AddInstruction classes is when setting up the array, anonymous classes are a good way to make it a little faster.


If by "make method calls dynamically" you mean making method calls against an interface and let Java choose which code is executed: This is simply polymorphism via dynamic dispatch, so provide different implementations:

class Mov implements Instruction {
    void instr(int a, int b) {
        // code for moving here
    }
}

class Add implements Instruction {
    void instr(int a, int b) {
        // code for adding here
    }
}

You can then use instances of these implementations, e.g. in an array. Dynamic dispatch will choose the right code for each instance when calling instr. But I wonder if such a general interface and an array of implementing instances is a good design. If I could, I'd use more specific interfaces and hold instances in separate variables. Your approach does make sense if you want to implement the Command pattern, i.e. you

  • have different clients that should be able to handle different sets of commands, or
  • want to queue or log or undo/redo all the commands.

If by "make method calls dynamically" you mean duck typing, this is only in a difficult way possible, see this conference paper on the International Conference on Software Engineering 2011.


It seems like what you are trying to do is use functional pointers, which do not exist in Java, although it doesn't look like you definitely need to use them in this situation either. What you could do is use a regular switch statement like so.

public static void runMethod(int whichone)
{
    switch(whichone)
    {
        case 0: drawCircle(); break;
        case 1: etc...  break;
    }

}

Then you can just call runMethod with the appropriate parameter.

public static void main(Strign[] args)
{
     runMethod(0);
     runMethod(3);
     etc...
}


Again, a command pattern which you could implement with a Map...

import java.util.HashMap;
import java.util.Map;

public class CommandEg {
   private static Map<String, Instruction> instructionMap = new HashMap<String, Instruction>();

   public static void main(String[] args) {
      instructionMap.put("mov", new Instruction() {
         public void instr(int a, int b) {
            // TODO: code to do mov action
         }
      });
      instructionMap.put("add", new Instruction() {
         public void instr(int a, int b) {
            // TODO: code to do add action
         }
      });

      instructionMap.get("mov").instr(1, 4);
      instructionMap.get("add").instr(4, 8);
   }

}

interface Instruction {  
   void instr( int a, int b );
}


you can use simple switch case for it....

switch(function)//function is an int value
{
case 1:circle();
case 2:rectangle();
.
.
.
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜