Java 可以将方法存储在数组中吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2172718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:51:08  来源:igfitidea点击:

Can Java store methods in arrays?

javaarraysmethods

提问by Paul

Well I wrote some code and all I was doing was for loops, but changing which method I called. I tried using a for loop so it'd be a bit neater (and out of curiosity to see if it could be done), but it doesn't compile when I do it this way, because it doesn't recognize an item in an array as a method, I think. This is what I have:

好吧,我写了一些代码,我所做的只是 for 循环,但更改了我调用的方法。我尝试使用 for 循环,所以它会更整洁(出于好奇,看看它是否可以完成),但是当我这样做时它不会编译,因为它无法识别中的项目我认为将数组作为一种方法。这就是我所拥有的:

String[] moveArray = {moveRight,moveDown,moveLeft,moveUp};
for (i = 0; i < 4; i++) {
    while (myWumpus.moveArray[i]) {
        myWumpus.moveArray[i];
        generator.updateDisplay();
    }
}

When I try compile I get

当我尝试编译时,我得到

not a statement myWumpus.moveArray[i]();
';' expected myWumpus.moveArray[i]();

(It refers to the first statement in the while loop)

(指的是while循环中的第一条语句)

So, I think it's maybe because I'm making it an Array of type String? Is there a type Method? Is this at all possible? Any solutions welcome :). Also, I can get it to work using 4 while loops, so you don't need to show me that solution. Thanks!

所以,我想这可能是因为我把它变成了一个 String 类型的数组?有类型方法吗?这是可能吗?欢迎任何解决方案:)。此外,我可以使用 4 个 while 循环使其工作,因此您无需向我展示该解决方案。谢谢!

回答by Avi

You cannot store methods directly in arrays. However you can store objects, which implement the same method differently. For example:

您不能直接在数组中存储方法。但是,您可以存储对象,它们以不同的方式实现相同的方法。例如:

Mover[] moveArray = {new RightMover(), new DownMover() new LeftMover(), new UpMover() };
for (i = 0; i < 4; i++) {
    while (myWumpus.moveArray[i]) {
        moveArray[i].move();
        generator.updateDisplay();
    }
}

回答by Claudiu

You can't store methods in arrays in Java, because methods aren't first-class objects in Java. It's a reason some people prefer to use other languages like Python, Scheme, etc.

您不能在 Java 中将方法存储在数组中,因为方法不是 Java 中的一流对象。这是一些人更喜欢使用其他语言(如 Python、Scheme 等)的原因。

The work-around is to create an interface which contains one method, then create four classes implementing that interface - the MoveRight, MoveLeft, etc... classes. Then you can store instances of those classes in your array and call them all the same way.

解决方法是创建一个包含一个方法的接口,然后创建四个实现该接口的类 - MoveRight、MoveLeft 等...类。然后您可以将这些类的实例存储在您的数组中并以相同的方式调用它们。

回答by brabster

Yes, you can store methods in arrays using Reflection, however it is likely that what you actually want to do in this situation is use polymorphism.

是的,您可以使用Reflection将方法存储在数组中,但是在这种情况下您实际上想要做的很可能是使用polymorphism

As an example of polymorphism in relation to your problem - say you created an interface as follows:

作为与您的问题相关的多态性示例 - 假设您创建了一个接口,如下所示:

public interface MoveCommand {
    void move();
}

You can then create implementations as follows:

然后,您可以按如下方式创建实现:

public class MoveLeftCommand implements MoveCommand {
    public void move() {
        System.out.println("LEFT");
    }
}

etc. for the other move options. You could then store these in an MoveCommand[]or collection like a List<MoveCommand>, and then iterate over the array/collection calling move() on each element, for example:

等其他移动选项。然后,您可以将它们存储在MoveCommand[]类似 a的或集合中List<MoveCommand>,然后在每个元素上调用 move() 遍历数组/集合,例如:

public class Main {

    public static void main(String[] args) {
        List<MoveCommand> commands = new ArrayList<MoveCommand>();
        commands.add(new MoveLeftCommand());
        commands.add(new MoveRightCommand());
        commands.add(new MoveLeftCommand());

        for (MoveCommand command:commands) {
            command.move();
        }
    }

}

Polymorphism is very powerful, and the above is a very simple example of something called the Command Pattern. Enjoy the rest of your Wumpus World implementation :)

多态性非常强大,上面是一个非常简单的例子,叫做命令模式。享受您的 Wumpus World 实现的其余部分:)

回答by Bozho

You can't call methods like that. But you can using reflection:

你不能这样调用方法。但是你可以使用反射:

Just change the first line in the while-loop to:

只需将 while 循环中的第一行更改为:

Method m = myWumps.getClass().getMethod(moveArray[i]); // if the method is void
m.invoke(myWumps);

(you will have to declare/catch a few exceptions)

(您必须声明/捕获一些例外情况)

But you'd better avoid reflection, and use the Command patterninstead.

但是你最好避免反射,而改用命令模式

回答by cbender

Updated answer for Java 8 and onwards-

更新了 Java 8 及以后的答案-

Since the introduction of lambda expressionsand method referencesin Java 8, storing various methods in variables is now possible. One main issue is that arrays don't currently support generic objects in Java, which makes storing the methods in arrays less doable. However they can be stored in other data structures like a List.

由于在 Java 8 中引入了lambda 表达式方法引用,现在可以在变量中存储各种方法。一个主要问题是数组目前不支持 Java 中的通用对象,这使得将方法存储在数组中不太可行。但是,它们可以存储在其他数据结构中,例如List.

So for some simple examples you can write something like:

因此,对于一些简单的示例,您可以编写如下内容:

List<Comparator<String>> stringComparators = new ArrayList<>();
Comparator<String> comp1 = (s1, s2) -> Integer.compare(s1.length(), s2.length());
stringComparators.add(comp1);

or

或者

List<Consumer<String>> consumers = new ArrayList<>();
Consumer<String> consumer1 = System.out::println;
consumers.add(consumer1);

and then loop/iterate through the Listto get the methods.

然后循环/迭代List以获取方法。