2012-09-27 79 views
17

可能重複:
Java Pass Method as Parameter如何在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方法會有所不同

+12

[接口 - Java Pass方法作爲參數](http://stackoverflow.com/questions/2186931/java-pass-method-as-parameter?rq=1) – Aerus

+0

另請參見此答案http:// stackoverflow。 com/a/22933032/1010868 –

回答

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

@CrazyCasta ..這不是Java ..你應該寫'實現IRangeCheck'來實現一個接口.. –

+2

無論如何,這個概念站在.. – jrharshath

+0

@RohitJain好的,它已經有一段時間了,我實際上用Java編寫了任何東西。 – CrazyCasta

32

您應該使用interface做到這一點。

您將聲明所需函數的接口傳遞給該方法,並調用所需的方法。將被調用的具體方法是實現類實現的方法。它被稱爲strategy design pattern

代碼示例:

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

謝謝..今天學到了一些新東西.. :) – Amarnath

+1

如果我不得不選擇一個類似於這個想法的設計模式,我會選擇命令模式。 Stategy對我來說聽起來太複雜了,通常意味着存在多種實現。 –

+0

@amit爲什麼你聲明接口是靜態的? – Celeritas

6

創建與方法簽名的接口,並通過它的一個子類,匿名您的方法實現。

// 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中的未來版本(與lambda表達式的出現),您將不必定義接口和匿名內部類 - 將有具體的lambda語法,這將彙編等效字節碼。

[1] Cannot refer to a non-final variable inside an inner class defined in a different method

+0

Java 7沒有lambda表達式。也許Java 8會在未來某個時候使用它們。 – Jesper

+0

正式注意 - 相應地編輯答案。 – jrharshath

2

可以創建定義所需的方法的接口,並通過實現該接口的類的對象。通常,匿名類用於此目的。

interface Worker { 
    public void callMe(); 
} 

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

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

你不能在java中傳遞方法。

你要做的是聲明一個接口,並獲取一個實現該接口的類的參數,這樣你就可以通過該參數調用該函數。

你可以在你的代碼中創建一個匿名類。

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); 
} 
+2

當所需方法屬於祖先類和/或兼容方法具有不同簽名時,您應該處理該情況。如果你傳遞'Double.class','void foo(double d)'不會被'getDeclaredMethod'匹配。 – Stephan

+1

您應該真正使用語言功能,例如帶有其他人提供的界面而不是反射的解決方案。反射不是類型安全的,比普通的方法調用慢。 – Jesper

1

不,將方法作爲參數傳遞是不可能的。我想,最好的方法是創建一個接口,編寫一個實現該接口的類(根據需要修改實現)並將該類的對象作爲參數傳遞。

也可以使用反射,將methodName作爲字符串傳遞給您的方法。並使用反射來調用該方法。

希望這有助於:-)

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

相關問題