Java中是否存在与C ++成员函数指针等效的内容?

时间:2010-11-25 18:40:52

标签: java c++

在你标记为dup之前,是的,我看过Function Pointers in Java,不,它没有真正回答我的问题,主要是因为我对Java很新,所以我真的不明白分配答案。

这是一些捣乱的Java / C ++,有没有合理的方法在Java中做到这一点?

public class Foo {
    private int _data;

    /* various other functions */    

    public boolean test1( Foo other ) {  /* do test */ }
    public boolean test2( Foo other ) {  /* do test */ }
    public boolean test3( Foo other ) {  /* do test */ }
    public boolean test4( Foo other ) {  /* do test */ }
}

public class Bar {
    private Foo[] _foos = { /* Init an array of Foos */ };

    public Bar doSomething() {
        _foos = new Foo[4];

        _foos[0] = getTest(Foo::test1);
        _foos[1] = getTest(Foo::test2);
        _foos[2] = getTest(Foo::test3);
        _foos[3] = getTest(Foo::test4);
    }

    /* 
     * Now we only have a single function which takes function pointer.
     */
    private Foo _getTest(boolean Foo::*func()) {
        Foo current = _foos[ 0 ];

        for ( int i = 1; i != _foos.length; i++ )
            current = current.*func( _foos[ i ] ) ? _foos[ i ] : current;

        return current;
    }
}

5 个答案:

答案 0 :(得分:8)

不,在Java中根本就没有函数这样的东西。只有对象和方法完全由对象拥有并从属于它们。对象是你在java中的主人和主人,没有任何事情可以通过他的意愿发生。

你可以通过让你的对象实现委托接口来实现一种java委托,就像它接近一样。

public interface Func {

boolean func(Foo foo);

}

public class Test1 implements Func {

@Override
public boolean func(Foo foo) {
  return doSomeStuff();
}

...

_foos[0] = getTest(new Test1());

希望这足以让我们了解这个想法。一般来说,你没有看到在应用程序代码中实际做得太多。

编辑:

由于您是Java新手,因此实际执行您尝试执行的操作的语法。这也可能说明它是什么皮塔饼以及为什么人们不喜欢它:)

public class Bar {

  public static interface Func {
    boolean func(Foo current, Foo other);
  }

  public static Func test1 = new Func() {
    @Override
    public boolean func(Foo current, Foo other) {
      return current.test1(other);
    }
  };

  public Bar doSomething() {
    _foos = new Foo[4];
    _foos[0] = getTest(test1);
    //...
  }

  private Foo _getTest(Func func) {
    Foo current = _foos[ 0 ];

      for ( int i = 1; i != _foos.length; i++ ) {
        current = func(current, _foos[ i ] ) ? _foos[ i ] : current;
      }
    return current;
  }

}

答案 1 :(得分:2)

Java中的函数不是第一类对象。这意味着您可以通过子类化或实现接口来实现此目的的最佳方式。该接口将包含方法定义。然后,您将实际使用所需方法传递对象。请参阅Collection.sort的工作原理。

答案 2 :(得分:2)

JDK8可能会引入lambda和方法引用。

同时,匿名内部类提供了一种略微冗长的创建仿函数对象的方法。

public interface FooTest {
    boolean test(Foo foo);
}
[...]
    FooTest[] tests = {
         new FooTest() { public void boolean test(Foo foo) {
             return foo.test1();
         }},
         [...]
    };

为了构建测试框架之类的东西,那么使用注释处理器进行反射或静态代码生成是可行的方法。 (请注意,通常反射是邪恶的,但在测试框架等情况下也没问题。)

答案 3 :(得分:1)

你不能指向Java中的函数,也没有直接的等价函数。

我唯一能想到的就是Function对象。你知道,在C ++中你会重载函数调用运算符,

operator()

在Java中,您创建了一个名为Function的接口,其中包含一个虚方法doSomething,而不是像在C中那样使用函数指针数组,而是有一个{{1}的数组然后调用Function方法的对象。

答案 4 :(得分:0)

根据语言的差异,将您的示例或多或少直接转换为Java。

public abstract class PTMF { // Pointer To Member Function         
    // The object on which we are going to call the method
    public Foo self;
    // Common interface of the member functions we are going to call
    public abstract boolean test(Foo other);
}

public class Foo {
    private int _data;

    /* various other methods */
    public boolean test1(Foo other) { /* do test */ }
    public boolean test2(Foo other) { /* do test */ }
    public boolean test3(Foo other) { /* do test */ }
    public boolean test4(Foo other) { /* do test */ }
}

public class Bar {
    private Foo[] _foos = { /* Init an array of Foos */ };

    public Bar doSomething() {
        _foos = new Foo[4];

        // Here we are going to define inline some PTMFs
        // providing adapter implementations for our interface call.

        _foos[0] = getTest(
            new PTMF() {                    
                @Override public void test(Foo other) { 
                    return self.test1(other);
                }
            }
        );
        _foos[1] = getTest(
            new PTMF() {
                @Override public void test(Foo other) { 
                    return self.test2(other);
                }
            }
        );
        _foos[2] = getTest(
            new PTMF() {
                @Override public void test(Foo other) { 
                    return self.test3(other);
                }
            }
        );
        _foos[3] = getTest(
            new PTMF() {
                @Override public void test(Foo other) { 
                    return self.test4(other);
                }
            }
        );
    }

    /* 
     * Now we only have a single function which takes function pointer.
     */
    private Foo getTest(PTMF ptmf) {
        Foo current = _fos[0];

        for ( int i = 1; i != _foos.length; i++) {
            // Set reference to called object
            ptmf.self = current;
            // Call PTMF
            current = ptmf.test( _foos[ i ] ) ? _foos[ i ] : current;
        }    
        return current;
    }
}

请注意,在上面的示例中,PTMF不是线程安全的。对于线程安全的实现,请将PTMF更改为

public class PTMF {
    public abstract boolean test(Foo self, Foo other);
};

或者,在这种情况下更好:

public interface PTMF {
    boolean test(Foo self, Foo other);
};

并且getTest()中的循环体将是:

current = ptmf.test(current, _foos[ i ] ) ? _foos[ i ] : current;