Java方法 - 采用一种方法作为论据

时间:2009-05-20 11:43:24

标签: java methods

我遇到了一些我无法在此分享的代码,但声明方法 WITHIN 另一种方法的参数列表。我甚至都不知道这是可能的。我真的不明白为什么这样做。有人可以向我解释一下你作为程序员可能会做的一些可能的用途吗? (注意:因为我不能显示代码,所以我不希望在上下文中解释一般)

相关:

  

What's the nearest substitute for a function pointer in Java?

12 个答案:

答案 0 :(得分:24)

代码看起来像这样吗?

obj.someMethod(myVar,3,new FooObject() {
  public void bar() {
    return "baz";
  }
});

如果是这样,那么该方法不会作为参数传递给另一个方法,而是正在创建anonymous inner class,并且该类的实例将作为参数传递。

在上面的示例中,FooObject是一个不实现bar()方法的抽象类。我们不是创建扩展private class的{​​{1}},而是创建抽象类的实例,并根据其余代码提供抽象方法的实现。

您无法创建抽象类的实例,因此我们必须提供缺少的方法来创建完整的类定义。由于这个新类是动态创建的,因此没有名称,因此匿名。因为它是在另一个类中定义的,所以它是一个匿名的内部类。

它可以是一个非常方便的快捷方式,特别是对于FooObject类,但如果你被带走并且内联方法定义太长,它可能会使你的代码难以理解。

答案 1 :(得分:4)

在Java中,您无法将方法作为参数传递。难道它不是通过一个方法,而是一个匿名的内部阶级?

这对于在类之间传递行为非常有用。谷歌“依赖注入”或“控制反转”获取更多信息。

答案 2 :(得分:4)

你见过Functional Java吗? 这是一个非常有趣的库,允许您像在Scala中那样进行编程。 I Wrote关于这个库。我承认最好使用更灵活的语法(BGGA闭包),如Scala。

将Functional Java与列表中的map等高阶函数一起使用:

final List<Integer> numbers = list(1, 2, 3, 4, 5);  

List<Integer> c = numbers.map(new F<Integer, Integer>() {  
                 public Integer f(Integer arg) {  
                   return arg * arg;  
                  }  
              });  

另一个有用的lib是lambdaj,它提供了很好的方式来玩,如功能(FP)编程。 与FP语言相比,Java的语法有限。但你仍然可以利用FP风格的一些优势,但你必须有创意!

答案 3 :(得分:3)

使用java.lang.reflect.Method

例如

public void callMethod(Method aMethod, int value) throws Exception {
    aMethod.invoke(this, value);
}

public void print(Integer value) {
    System.out.print(value);
}

public void println(Integer value) {
    System.out.println(value);
}

public void demo() throws Exception {
    Method println = this.getClass().getMethod("println", Integer.class);
    Method print = this.getClass().getMethod("print", Integer.class);
    callMethod(println, 10);
    callMethod(print, 10);
}

答案 4 :(得分:3)

在Java中传递函数指针最接近的事情是传递抽象类或接口的匿名实例。例如,泛型函数类型可以在这样的接口中编码:

public interface F<A, B> {
  public B f(final A a);
}

然后,您可以在另一个方法的参数列表中预期一个方法:

public List<B> map(List<A> as, F<A, B> f) {
  ...
}

您可以使用该界面的匿名实例调用它:

map(myList, new F<Integer, String>() {
  public String f(Integer i) {
    return String.valueOf(i);
  }
});

有一个名为Functional Java的库,它正好利用了这个想法,为光荣的语言Java带来了巨大的好处。

答案 5 :(得分:1)

本身并不是Java中的合法语法。它是否可能创建一个匿名类的新实例?

答案 6 :(得分:1)

您也可以这样做:

final Predicate somePredicate = new Predicate<Item>() 
  {
  @Override
  public boolean apply(Item item)
    {
    return item.someProperty().equals(something);
    }
  }

并像这样使用它:

List<Item> filteredList = filter(list, somePredicate);

我之前做过这样的事情。我还编写了一些方法,使用闭包来以类似的方式构建和返回接口的匿名实现:

Predicate isSomeColor(final Color color)
  {
  return new Predicate<Shape>() 
    {
    @Override
    public boolean apply(Shape shape)
      {
      return shape.getColor().equals(color);
      }
    }
  }

List<Shape> redShapes = filter(shapes, isSomeColor(Color.RED);

所有这些仍然是匿名内部类。我实际上没有在命名类本身,我只是引用了类的实例。

答案 7 :(得分:0)

这称为reflection。有一整个对象库代表构造函数,方法等等 例如,您可以使用它来调用在运行时确定的动态method

答案 8 :(得分:0)

是的,可以在另一个方法的参数列表中声明方法。你可以看一下java.lang.reflect.Method

使用反射,您可以检索一个Method对象,该对象表示您希望作为参数传递的方法。然后,您可以调用Method来调用该方法。

此外,您可以参考“Java语言中的函数式编程”( http://www.ibm.com/developerworks/java/library/j-fp.html ),它可以为您提供从里到外的例子。

答案 9 :(得分:0)

上述答案的变化是否可能。是否有可能通过反思?可以通过使用匿名内部类吗?我们需要澄清一下。

答案 10 :(得分:0)

最接近函数参数的是

一个只有一个方法的匿名类的实例。

    Runnable a = new Runnable(){

   run(){
    System.out.println("hello");
        }
    }

  myMethod(a);

答案 11 :(得分:0)

不是指针,但你仍然可以通过一些技巧内联编写函数。

在另一个answer

上查看我的thread