在Java中如何将方法作为参数传递?

在Java中如何将方法作为参数传递?,java,Java,可能重复: 在Java中是否可以将方法作为参数传递?如果我不能确定,对于下面的方法,不必重复代码的最佳做法是什么 public void enterUserInput(javax.swing.JTextField inputField, javax.swing.JTextField outputField, method rangeChecking){ String input; double output; input = inputField.getText(

可能重复:

在Java中是否可以将方法作为参数传递?如果我不能确定,对于下面的方法,不必重复代码的最佳做法是什么

public void enterUserInput(javax.swing.JTextField inputField, javax.swing.JTextField   outputField, method rangeChecking){

    String input;
    double output;
    input = inputField.getText();
    output = Double.parseDouble(input);
    if(rangeChecking(output)){
        outputField.setText(input);
        inputField.setText(null);
    }

我将从不同的类调用rangeChecking方法,每次调用enterUserInput时,rangeChecking方法都会不同,据我所知不是这样。这通常是通过创建一个具有所需方法的接口并在中传递一个实现该接口的类来实现的

public interface IRangeCheck
{
    boolean check(double val);
}

public class RangeChecker implements IRangeCheck
{
    public boolean check(double val)
    {
        return val > 0.0;
    }
}

...
    public void blabla(..., IRangeCheck irc)
    {
        ...
        if(irc.check(output))
           ...
    }
你应该用一个字母来做这件事

将声明所需函数的接口传递给方法,并调用所需方法。将被调用的特定方法是由实现类实现的方法

它被称为

代码示例:

public static interface Foo { //this is the interface declaration
    public void print();
}
public static class Bar implements Foo { //Bar is an implementing class
    public void print() {
        System.out.println("Bar");
    } 

}
public static void test(Foo foo) { //the method accepts an interface
    foo.print(); //and invokes it, the implementing class' print() will be invoked.
}
public static void main(String... args) throws Exception {
    test(new Bar()); //invoke test() with the class implementing the interface
}

使用该方法签名创建一个接口,并将其匿名子类与方法实现一起传递

// the interface that contains the method/methods you want to pass
interface MethodWrapper {
    public void method(String s); }

// ...
// in your code
// assuming that "observable" is an object with a method "setCallback" that 
// accepts the callback
// note that your method implementation will have access to your local variables

public void someMethodOfYours() {
    observable.setCallback(new MethodWrapper() {
        public void method(String s) {
            System.out.println(s);
        } }
    );
    // note that your anon subclass will have access to all your contain method 
    // locals and your containing class members, with [some restrictions][1]
}

// in the "observable" class - the class that receives the "callback method"
// ...

if( updated() ) {
    callback.method("updated!"); }
在未来的java版本中(随着lambdas的出现),您将不必定义接口和匿名内部类-将有特定的lambda语法编译成等效的字节码


[1]

您可以创建一个定义所需方法的接口,并传递实现该接口的类的对象。通常,匿名类用于此目的

interface Worker {
    public void callMe();
}

public function callWorker(Worker w) {
    w.callMe();
}

callWorker(new Worker() {
    public void callMe() {
        System.out.println("Hi there!");
    });

在java中不能传递方法

您要做的是声明一个接口,并获取一个实现该接口的类作为参数,这样您就可以通过该参数调用函数


您可以在代码中创建一个匿名类

您可以使用java反射

public void enterUserInput(javax.swing.JTextField inputField, javax.swing.JTextField   outputField, String methodName){

String input;
double output;
input = inputField.getText();
output = Double.parseDouble(input);
Method m = this.getClass().getDeclaredMethod(methodName, Double.class);

if((Boolean)m.invoke(this, output)){
    outputField.setText(input);
    inputField.setText(null);
}

不,不可能将方法作为参数传递

我想,最好的方法是创建一个接口,编写一个实现该接口的类(根据需要修改实现),并将该类的对象作为参数传递

还可以使用反射,将methodName作为字符串传递给方法。并使用反射调用该方法


希望这能有所帮助:-)

使用有一些方法可以做到这一点,但最好避免。您要做的是创建一个界面,如:

    public interface RangeChecker {

    boolean rangeChecking(double input);


}
然后为每个范围检查方法创建实现:

    public class SomeRangeCheck implements RangeChecker {

    public boolean rangeChecking(double input) {
        // do something
    }

}
然后,另一个方法的签名变成:

public void enterUserInput(JTextField inputField, JTextField   outputField, RangeChecker rangeChecking)

您可以传递实现RangeChecker接口的任何对象。

另请参见此答案。当所需方法属于祖先类和/或兼容方法具有不同签名时,您应该处理这种情况
void foo(double d)
如果通过
getDeclaredMethod
则不会与之匹配
double.class
。您应该真正使用语言功能,例如解决方案与他人提供的接口,而不是反射。反射不是类型安全的,并且比常规方法调用慢。@CrazyCasta。。那不是Java。。您应该编写
implements IRangeCheck
来实现一个接口。。不管怎样,这个概念是正确的。@RohitJain很好,我已经有一段时间没有用Java编写任何东西了。@jrhashas。。是的,我没有否认。。无意冒犯。在我看来,更好的名称应该是
interface RangeChecker
greetherzero实现RangeChecker
。谢谢。。今天学到了一些新东西……)如果我必须选择一种类似于这个想法的设计模式,我会选择命令模式。对我来说,策略听起来太复杂了,它通常意味着存在多个实现。@amit为什么要将接口声明为静态?@Celeritas,因为它是一个内部类。如果不将其作为内部类(在其自己的文件中),则无需将接口声明为静态。另外,由于java8-这个答案有点令人费解,引入了\.Java7没有lambda表达式。也许Java 8在将来的某个时候会有它们。。