Подтвердить что ты не робот

Как передать метод в качестве параметра в Java?

Возможный дубликат:
Java Pass Method как параметр

Можно ли передать метод в качестве параметра в 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 будет отличаться

4b9b3361

Ответ 1

Для этого вы должны использовать interface.

Вы передаете интерфейс, объявляющий желаемую функцию, и вызываете желаемый метод. Конкретный метод, который будет вызываться, - это тот, который реализуется реализующим классом.

Он называется шаблон разработки стратегии.

пример кода:

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
}

Ответ 2

Не знаю, насколько я знаю. Обычно это делается с помощью интерфейса, который имеет тот метод, который вы хотите, и передачи класса, который реализует этот интерфейс.

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))
           ...
    }

Ответ 3

Создайте интерфейс с этой сигнатурой метода и передайте анонимный подкласс его реализации вашего метода.

// 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 (с появлением лямбда) вам не нужно будет определять интерфейс и анонимный внутренний класс - там будет конкретный синтаксис лямбда, который будет компилироваться в эквивалентный байт-код.

[1] Нельзя ссылаться на не конечную переменную внутри внутреннего класса, определенного другим способом

Ответ 4

Вы можете использовать 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);
}

Ответ 5

Есть способы сделать это, используя 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.

Ответ 6

Вы можете создать интерфейс, который определяет необходимый метод, и передать объект класса, который реализует этот интерфейс. Часто для этого используются анонимные классы.

interface Worker {
    public void callMe();
}

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

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

Ответ 7

вы не можете передать метод в java.

то, что вы делаете, объявляет интерфейс и получает в качестве параметра класс, реализующий интерфейс, таким образом вы можете вызвать функцию через параметр.

вы могли бы в своем коде создать анонимный класс.

Ответ 8

Нет, передача методов в качестве аргумента невозможна.

Я думаю, лучший подход - создать интерфейс, написать класс, который реализует это (модифицировать реализацию по мере необходимости) и передать объект класса в качестве аргумента.

Также вы можете использовать отражение, передать методName как String в свой метод. и использовать отражение для вызова этого метода.

Надеюсь, что это поможет: -)