Java 如何将数组链接到方法

Java 如何将数组链接到方法,java,arrays,syntax,Java,Arrays,Syntax,这个问题主要针对Java,但如果它适用于所有面向对象编程语言,那就好了 我想知道是否有办法将数组值链接到某个方法。我有一个包含许多方法的程序,当巨型if脚本中存在某个条件时,会运行一个方法。我觉得这样做既慢又低效。我想知道是否可以创建一个数组,其中每个值都链接到要执行的相应方法 例如:如果我有一个0-99之间的数字,我想根据我选择的数字运行某个方法。我是否可以制作一个具有相应方法的数组,而不是生成一个包含100个不同案例的if脚本?所有的方法都在一个类中,每个数字都有自己的方法。它看起来像这样:

这个问题主要针对Java,但如果它适用于所有面向对象编程语言,那就好了

我想知道是否有办法将数组值链接到某个方法。我有一个包含许多方法的程序,当巨型if脚本中存在某个条件时,会运行一个方法。我觉得这样做既慢又低效。我想知道是否可以创建一个数组,其中每个值都链接到要执行的相应方法

例如:如果我有一个0-99之间的数字,我想根据我选择的数字运行某个方法。我是否可以制作一个具有相应方法的数组,而不是生成一个包含100个不同案例的if脚本?所有的方法都在一个类中,每个数字都有自己的方法。它看起来像这样:

int num = 73;
methods[num](parameters);

我不知道这样的事情是否可能发生。非常感谢您的帮助

在我正在编写的程序中,我通过使用覆盖方法创建构造函数来实现这一点

public class Script 
{
    public Script()
    {

    }

    public void run()
    {

    }
}

public class TestScript extends Script
{
    public TestScript()
    {

    }

    public void run()
    {
        //This Method overwrites the run method of script. This is where your code goes.
    }
}

public class Main
{
    public static Script test = new TestScript();

    public static void main(String[] args)
    {
        test.run();
    }
}
定义一个接口(将其命名为
ScriptTask
),定义要执行的方法(将其命名为
execute
)。创建
ScriptTask
的数组任务。然后使用
任务[num]。执行(参数)

例如:

@FunctionalInterface
interface ScriptTask {
    void execute(String s, int i);
}

class Script {

    private ScriptTask[] tasks;

    Script() {
        this.tasks = new ScriptTask[2];
        this.tasks[0] = this::foo;
        this.tasks[1] = this::bar;
    }

    private void foo(String s, int i) {
        System.out.println(s);
    }

    private void bar(String s, int i) {
        System.out.println(i);
    }

    void run() {
        for (int i = 0; i < tasks.length; i++) {
            tasks[i].execute("hello", i);
        }
    }

    public static void main(String[] args) {
        new Script().run();
    }
}
@functioninterface
接口脚本任务{
void execute(字符串s,int i);
}
类脚本{
私有脚本任务[]任务;
脚本(){
this.tasks=新脚本任务[2];
this.tasks[0]=this::foo;
this.tasks[1]=this::bar;
}
私有void foo(字符串s,int i){
系统输出打印项次;
}
专用空心条(字符串s,整数i){
系统输出打印LN(i);
}
无效运行(){
for(int i=0;i

请注意,如果在一个类中确实有100个不同的方法,这就清楚地表明应该将它重构为几个不同的更简单的类,这些类可以更容易地读取、理解和测试。以上是重构的第一步:您可以将每个方法重构为实现ScriptTask接口的单独类。

可以创建一个接口来保存要运行的方法,例如:

public interface MethodRunner {
   public void run();
} 
定义数组并添加MethodRunner的实例

MethodRunner[] methodsRunners = new MethodRunner[n];
methodsRunners[0] = new MethodRunner() {
      @Override
      public void run() {
        // some method here 
      }
};
methodsRunners[0] = ... 
      . 
      . 
methodsRunners[n] = ... 
并按以下方式运行:

methodsRunners[n].run();

好吧,我认为我们可以利用反射来实现这一点,如下所示“

1.)类来存储有关方法的信息

public class MethodInfo {

    public String methodName;
    public Class<?>[] params;
}
public class Task {

    public void method1(int x, ......){

    }
    And So On..
}
3.)创建并使用数组的主类。在这里,使用反射,我们可以从数组访问方法并调用它们

public class MainClass {

    public static void main(String[] args) {

        MethodInfo firstMethod = new MethodInfo();
        firstMethod.methodName = "method1";
        firstMethod.params = Array OF Parameter Types(.class values)

        MethodInfo[] methods = new MethodInfo[10];
        methods[1] = firstMethod;

        java.lang.reflect.Method method = Task.class.getMethod(methods[1].methodName, methods[1].params);
        method.invoke(new Task(), param1, param2,....);
    }
}

除了JB Nizet的答案外,还可以使用其他语法变体:

    this.tasks = new ScriptTask[4];
    this.tasks[0] = this::foo;
    this.tasks[1] = this::bar;
    this.tasks[2] = (String s, int i) -> {
        System.out.println(s);
    };
    this.tasks[3] = (String s, int i) -> System.out.println(s);
甚至:

   this.tasks = new ScriptTask[] {
        this::foo,
        this::bar,
        (String s, int i) -> {
            System.out.println(s);
        },
        (String s, int i) -> System.out.println(s)
    };
我想知道是否有办法将数组值链接到某个方法

您可以使用反射来生成一系列方法。但是,这是一个“不理想的解决方案”,因为它会使您的代码难以维护。因此,我不得不说,这不是一个好的做法,但事实就是这样

package methodarray;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodArray {
    public static void main(String[] args) {
        Method[] arrayOfMethods = new Method[100];
        try {
            //...You will need to add the methods by their name, you can use for loops to add them quickly
            arrayOfMethods[1] = MethodArray.class.getDeclaredMethod("someMethodName");
            arrayOfMethods[2] = MethodArray.class.getDeclaredMethod("someOtherMethod");
            //...
        } catch (NoSuchMethodException | SecurityException ex) {
            //this can throw an Exception if the method is not found, handle it here
        }
        //now to call a method from the array just do
        try {
            arrayOfMethods[1].invoke(MethodArray.class);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            //...handle exceptions
        }
    }

    public void someMethodName(){
        //...logic
    }

    public void someOtherMethod(){
        //...logic
    }
}
这将有助于您按照自己的意愿调用方法,但请记住,为了安全起见,java在使用反射时可能会抛出几个期望值。要发送其他参数,只需调用
arrayOfMethods[n].invoke(MethodArray.class,args[]);

这个问题主要针对Java,但如果它适用于所有面向对象编程语言,那就好了

为了解决这些类型的常见场景,我们使用设计模式,模式是针对常见场景的测试解决方案。所有答案都说您应该“使用接口”“实际上,您正试图帮助您实现这一目标,您可能会使用的模式称为
命令模式
,您可以了解它。理解或阅读模式可能没有用,因为您已经说过您不熟悉使用接口。(就我个人而言,我总是推荐
Head-First设计模式
作为模式的入门书。)


一旦您了解了命令模式,就可以简单地生成命令数组,记住这是一个更好的OO解决方案。我不会举一个例子,因为我认为很难理解,如果你对如何使用接口没有一个清晰的概念,阅读它们,这将是值得的

您需要传递定义方法的类的对象,从数组中获取方法名并传递参数。只发布所需的代码

public static Object invokeExactMethod(Object object, String methodName, Object... args) {
        if (null == args) {
            args = ArrayUtils.EMPTY_OBJECT_ARRAY;
        }
        int arguments = args.length;
        Class<?>[] parameterTypes = new Class[arguments];
        for (int i = 0; i < arguments; i++) {
            parameterTypes[i] = args[i].getClass();
        }
        return invokeExactMethod(object, methodName, args, parameterTypes);
    }


    invokeExactMethod() is method provided my MethodUtils class of apache commons.
publicstaticobjectinvokeexactmethod(Object对象、stringmethodname、Object…args){
if(null==args){
args=ArrayUtils.EMPTY\u OBJECT\u数组;
}
int参数=args.length;
类[]参数类型=新类[参数];
for(int i=0;i

希望这有帮助

您是否为每个数字都有一个方法或一个数字范围(如为10到20的所有数字运行method1)定义一个接口(我们将其命名为ScriptTask)定义要执行的方法(我们将其称为execute)。创建ScriptTask的数组
tasks
。然后使用任务[num]。执行(参数);每个数字都有自己的方法。每个数字都有自己的方法,但是所有的方法都与一个特定的类相关吗?我应该如何声明方法和数组?我不习惯使用接口。我知道它们是什么,但我不知道如何正确声明它们。是的,它们可以,你可以使用
@functioninterface
实现它,因为@JB answere我不知道这一点,因为我不久前搜索了这样一个解决方案,非常简洁。我也许可以利用它。@ngueno从概念上讲,函数接口只有一个抽象方法。请不要用c