如何在Java中按名称(String)调用方法?

时间:2013-09-10 11:50:04

标签: java

A的每个实例都有一个类B的实例。 A应根据其成员变量B调用method_num中的不同方法。这是一个实现我想要的实现:

public class A {
    private B myB = new B();
    public int method_num = 1;
    public callBMethod() {
        if ( method_num == 1 )
            myB.method1();
        else
            myB.method2();
    }
}

public class B {
    public method1() { }
    public method2() { }
}

但我希望能够以某种方式直接传递B myA.method_num = 1method1,而不是method2。我怎么能这样做?

5 个答案:

答案 0 :(得分:4)

你做不到。 Java不会将函数视为第一类对象,因为它没有Python或C#等功能特性。

您可以创建一个Command接口并传递该对象引用:

public interface Command {
    void execute(Object [] args);
}

答案 1 :(得分:3)

我认为您可以使用this之类的反射:

java.lang.reflect.Method method;
try {
  method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
  // ...
} catch (NoSuchMethodException e) {
  // ...
}  

try {
  method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {  //do proper handling
} catch (IllegalAccessException e) {//do proper handling
} catch (InvocationTargetException e) {//do proper handling

答案 2 :(得分:3)

如果您不想使用反射(这是一个很好的目标),那么enum的一些简洁功能允许您设置enum作为代理。< / p>

public class A {
  private B myB = new B();
  public int method_num = 1;

  public void callBMethod() {
    // Could do it by name.
    BMethods.valueOf("method1").call(myB);
    // Or by number.
    BMethods.values()[method_num].call(myB);
  }

}

enum BMethods{
  method1 {
    @Override
    public void call(B b) {
      b.method1();
    }
  },
  method2 {
    @Override
    public void call(B b) {
      b.method2();
    }
  };

  public abstract void call (B b);
}

public class B {
  public void method1() {
  }

  public void method2() {
  }

}

答案 3 :(得分:2)

也许使用Runnable个对象?您可以从B传递runnable,并直接从A

调用.run()

答案 4 :(得分:0)

Java反射API为您提供了一种方法,其中Method类型的对象可以与目标对象一起传递,然后可以在目标对象上调用该方法。

示例如下:

Method m; // The method to be invoked

  Object target; // The object to invoke it on

  Object[] args; // The arguments to pass to the method

  // An empty array; used for methods with no arguments at all.
  static final Object[] nullargs = new Object[] {};

  /** This constructor creates a Command object for a no-arg method */
  public Command(Object target, Method m) {
    this(target, m, nullargs);
  }

  /**
   * This constructor creates a Command object for a method that takes the
   * specified array of arguments. Note that the parse() method provides
   * another way to create a Command object
   */
  public Command(Object target, Method m, Object[] args) {
    this.target = target;
    this.m = m;
    this.args = args;
  }

  /**
   * Invoke the Command by calling the method on its target, and passing the
   * arguments. See also actionPerformed() which does not throw the checked
   * exceptions that this method does.
   */
  public void invoke() throws IllegalAccessException,
      InvocationTargetException {
    m.invoke(target, args); // Use reflection to invoke the method
  }