1

是否可以在 Java 中调用基于字段值的方法?例如,我问用户他们想要什么苏打水。他们输入他们的选择,保存他们选择的字段的值用于调用该方法。

显然下面的代码不起作用。但我希望它能说明我的意图。这种事情在Java中甚至可能吗?

目标是在不使用 IF 或 SWITCH 语句的情况下进行有效切换。

import java.util.Scanner;

public class FieldResolutionTest
{
     public static void main (String[] args)
     {
         Scanner inputScanner = new Scanner(System.in);
         MethodTester test = new MethodTester();

         System.out.println("Please enter ONE or TWO");
         String selection = inputScanner.nextLine();

         test.(selection)();
     }
}

public class MethodTester
{
     public void ONE()
     {
         System.out.println("You ran method ONE");
     }

     public void TWO()
     {
         System.out.println("You ran method TWO");
     }
}
4

6 回答 6

7

反射在技术上可行的,但是如果您有有限数量的已知可能方法,则使用 switch 语句会更简单(或者if/else如果您没有 Java 7):

switch (selection) {
    case "ONE":
        test.ONE();
        break;
    case "TWO":
        test.TWO();
        break;
    // etc.
    default:
        System.out.println("Invalid method!");
        break;
}

如果方法是动态的,或者您正在测试很多类,并且您仍然想走反射路线,它看起来像这样:

try {
    Method m = MethodTester.class.getMethod(selection);
    m.invoke(test);
} catch (NoSuchMethodException nsme) {
    System.out.println("Invalid method!");
}
于 2012-04-20T21:59:44.063 回答
3

一个不错的方法是enum

public class FieldResolutionTest
{
  public static void main (String[] args)
  {
    Scanner inputScanner = new Scanner(System.in);

    System.out.println("Please enter ONE or TWO");
    String selection = inputScanner.nextLine();

    FieldResolutionTest.valueOf(selection).run();
  }
}

public enum MethodTester
{
  ONE { public void run()
  {
    System.out.println("You ran method ONE");
  }},
  TWO { public void run()
  {
    System.out.println("You ran method TWO");
  }};

  public abstract void run();
}
于 2012-04-20T22:05:32.720 回答
2

您可以使用反射。这是您的示例,修改最少:

import java.lang.reflect.Method;
import java.util.Scanner;

public class FieldResolutionTest {
     public static void main (String[] args) throws Exception {
         Scanner inputScanner = new Scanner(System.in);
         MethodTester test = new MethodTester();

         System.out.println("Please enter ONE or TWO");
         String selection = inputScanner.nextLine();

         Method method = MethodTester.class.getMethod(selection);
         method.invoke(test);
     }
}

class MethodTester {
     public void ONE() {
         System.out.println("You ran method ONE");
     }

     public void TWO() {
         System.out.println("You ran method TWO");
     }
}

当然,您需要添加一些错误处理。例如,您应该检查用户是否输入了允许的方法之一的名称,如下所示:

        Map<String, Method> methods = new HashMap<String, Method>();
        for (Method m: MethodTester.class.getMethods()) {
            methods.put(m.getName(), m);
        }

        if (methods.containsKey(selection)) {
            methods.get(selection).invoke(test);
        } else {
            System.err.println("No such method: " + selection);
        }
于 2012-04-20T22:07:25.793 回答
1

您需要测试输入值并调用相应的方法:

if(selection.equals("ONE")) test.ONE();
else if (selection.equals("ONE")) test.TWO();
else System.out.println("Unknown input!");
于 2012-04-20T22:01:00.447 回答
1

自 Java 7 发布以来,可以对字符串类型变量执行 switch-case 方法

switch(selection) {
    case "ONE":
    test.ONE();
    break;

    case "TWO":
    test.TWO();
    break;
}

同样,仅从 Java 7 开始可用。

于 2012-04-20T22:02:11.257 回答
0

正如 mellamokb 所说,您可以使用反射来调用该方法。通常代码看起来像 test.getClass().getMethod("ONE", null).invoke(..)

于 2012-04-20T22:05:30.643 回答