是否可以使用变量调用方法?

时间:2009-12-12 16:22:16

标签: java

在PHP(例如)中,您可以使用这种方式使用如下变量调用函数:

$funcname = "print";
$funcname("Whatever..."); // Same as: print("Whatever...");

Java中使用的方式是什么?

8 个答案:

答案 0 :(得分:17)

请记住,这种反射在Java中并不像在Ruby这样的功能导向语言中那样,甚至是(等待它)C#。 本身技术没有任何问题,但是你确实失去了编译器保护,这可能导致难以发现的错误或混淆代码,因为其他开发人员不会预料到这些类型的路径。我并不认为Java中的所有反思都被认为是有害的,但它绝对不是主流实践。请谨慎使用。

也许更好,更友好的Java解决方案是使用Command Pattern。使用“执行”方法创建一个类似函数的对象数组,该方法执行所需的各种操作。使用接口进行抽象。

public interface Command {
    public void execute();
}

public class Foo implements Command{
    public void execute() {
        // do some stuff 
    }
}

您可以在具体类或匿名内部类中实现Command并迭代命令数组:

List<Command> commandArray = new <Command>ArrayList();
commandArray.add(new Foo());
commandArray.add(new Command(){
    public void execute() {
        // some more stuff;
    }
});

for (Command command : commandArray){
    command.execute();
}

编辑:根据Adrian的评论,这里是一种从迭代值数组的变量调用方法/命令的方法:

public interface StringCommand {
    public void execute(String value);
}

stringCommand = new StringCommand(){
    public void execute(String value){
        System.out.println(value.toLowerCase());
    }
}

String[] stringAry = {"foo", "fu", "Whatever..."};

for(String value : stringAry){
    stringCommand.execute(value);
}

在Ruby中类似于:

string_command = lambda {|value| puts value.downcase }
["foo", "fu", "Whatever..."].each { |value| string_command.call(value)}

答案 1 :(得分:15)

您可以使用

Class<?> klass = object.getClass();
Method method = klass.getMethod("name", String.class); // parameter types, if any
method.invoke(object, "whatever"); // parameters, if any 

加上样板代码来捕获5个不同的异常(他们承诺在Java 7中引入一个常见的超类型)。

答案 2 :(得分:7)

虽然可以使用反射执行此操作,正如许多人所指出的那样,对于您在评论中提及的用例,回应询问“为什么?”的注释,我会使用界面代替。< / p>

答案 3 :(得分:6)

是。使用Method.invoke。还有一些例子here

答案 4 :(得分:2)

Java Reflection API可以提供此功能。 (不完全像PHP那样,你)

答案 5 :(得分:1)

你可以使用反射,但是如果你想要一个打印东西的方法,并且你想稍后改变那种行为,只需编写一个方法并调用它。

答案 6 :(得分:0)

您可以像其他人建议的那样使用反射。从语法上讲,它与你的预期完全不同。

答案 7 :(得分:0)

JDK的下一个版本 - JDK7可能会有闭包支持。 如果您不想等到2011年秋季正式发布,您可以尝试使用betta版本。 google for Java / JDK 7。