2012-09-27 69 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接口的对象。

相关问题