在你标记为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;
}
}
答案 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;