18

可能重复:
Java 传递方法作为参数

是否可以在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 方法都会有所不同

4

8 回答 8

32

您应该使用接口来执行此操作。

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

它被称为策略设计模式

代码示例:

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
}
于 2012-09-27T08:11:29.380 回答
8

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

// 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]不能引用以不同方法定义的内部类中的非最终变量

于 2012-09-27T08:13:00.907 回答
6

据我所知不是。这通常是通过创建一个具有您想要的方法的接口并传递一个实现该接口的类来完成的。

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))
           ...
    }
于 2012-09-27T08:11:07.417 回答
5

您可以使用 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);
}
于 2012-09-27T08:14:37.287 回答
4

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

    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 接口的对象。

于 2012-09-27T08:22:50.447 回答
2

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

interface Worker {
    public void callMe();
}

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

callWorker(new Worker() {
    public void callMe() {
        System.out.println("Hi there!");
    });
于 2012-09-27T08:13:42.140 回答
1

你不能在java中传递方法。

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

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

于 2012-09-27T08:13:44.703 回答
1

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

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

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

希望这可以帮助 :-)

于 2012-09-27T08:15:28.417 回答