我遇到了一些我无法在此分享的代码,但声明方法 WITHIN 另一种方法的参数列表。我甚至都不知道这是可能的。我真的不明白为什么这样做。有人可以向我解释一下你作为程序员可能会做的一些可能的用途吗? (注意:因为我不能显示代码,所以我不希望在上下文中解释一般)
What's the nearest substitute for a function pointer in Java?
答案 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)
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)