这个问题主要是针对Java的,但是如果它适用于所有面向对象的编程语言,那很好。
我想知道是否存在一种将数组值链接到特定方法的方法。我有一个包含许多方法的程序,当在巨型if脚本中存在特定条件时,该方法就会运行。我发现这很慢而且效率低下。我想知道是否可以创建一个数组,其中每个值都链接到要执行的相应方法。
例如:如果我有一个0到99之间的数字,并且我想根据我选择的任何数字运行某种方法。我可以制作一个具有相应方法的数组,而不是制作具有100种不同情况的if脚本吗?所有方法都在一个类中,每个数字都有自己的方法。看起来像这样:
int num = 73;
methods[num](parameters);
我不知道这样的事情是否可能。任何帮助将不胜感激!
答案 0 :(得分:4)
定义一个接口(将其命名为ScriptTask
),以定义要执行的方法(将其称为execute
)。创建ScriptTask
的数组任务。然后使用tasks[num].execute(parameters)
。
示例:
@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();
}
}
请注意,如果您在一个类中确实有100个不同的方法,则明确表明应将其重构为几个不同的更简单的类,以使其更易于阅读,理解和测试。上面是重构的第一步:您可以将每个方法重构为实现ScriptTask接口的单独类。
答案 1 :(得分:1)
您需要传递定义了方法的类的Object,从数组中获取方法名称并传递参数。仅发布所需的代码。
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.
希望这会有所帮助.. !!
答案 2 :(得分:0)
在我正在研究的程序中,我通过使用覆盖的方法创建构造函数来实现了这一目标。
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();
}
}
答案 3 :(得分:0)
可以创建一个接口来保存要运行的方法,例如:
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();
答案 4 :(得分:0)
好吧,我认为我们可以利用Reflection来实现此目标,如下所述”
1。)用于存储有关方法的信息的类
public class MethodInfo {
public String methodName;
public Class<?>[] params;
}
2。)由所有方法组成的类
public class Task {
public void method1(int x, ......){
}
And So On..
}
3。)主类创建数组并使用它。在这里,我们可以使用Reflection来访问数组中的方法并调用它们。
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,....);
}
}
答案 5 :(得分:0)
除了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)
};
答案 6 :(得分:0)
我想知道是否存在一种将数组值链接到特定方法的方法。
您可以使用反射来生成方法数组。但是,这是“不理想的解决方案”,因为它将使您的代码难以维护。所以,我不得不说这不是一个好习惯,但是在这里。
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的,但是如果它适用于所有面向对象的编程语言,那很好。
为解决这些类型的常见情况,我们使用 设计模式 ,模式是针对常见情况的经过测试的解决方案。所有回答都表明您应该“使用接口”实际上是在试图帮助您实现这一目标,您可能可以使用的模式称为Command Pattern
,您可以阅读有关here的信息。因为您已经说过您不熟悉使用接口,所以理解或阅读该模式可能没有用。 (我个人总是推荐Head First Design Patterns
作为有关模式的入门书籍。)
一旦您了解了命令模式,就可以简单地生成命令数组,这是一个更好的OO解决方案,请记住这一点。我不会举一个例子,因为如果您对如何使用接口没有清晰的想法,我很难理解,请阅读它们,那将是值得的!!!