指向Java中静态表的实例方法



我想要一个这样的表格:

static final Record [] table = {
new Record( Pattern.compile( "regex1" ), MyClass::f1 ),
new Record( Pattern.compile( "regex2" ), MyClass::f2 )
};

其中f1,f2等是对实例(非静态)方法的引用,每个方法都有一个参数和一个返回值,如下所示:

public int f1( int arg ) {
return arg * arg;
}
public int f2( int arg ) {
return arg + arg;
}

所以我可以像这样调用它们(伪代码):

void foo( String s, int arg ) {
for( Record r : table ) {
if( r.regex.matcher( s ).matches() ) {
int result = r.func.invokeOn( this, arg );
break;
}
}
}

在伪代码中声明Record构造函数的第二个参数(即成员变量func)的正确方法是什么?我为静态f1,f2等找到了它,但无论我如何尝试f1等的非静态声明,我都会得到各种相当难以理解的错误消息。我想这是可以做到的。

您可以使用BiFunction<MyClass, Integer, Integer>,假设MyClass是包含方法的类(或者使用接口而不是类)。对一个没有实例的非静态方法的方法引用(只给出了类),引入了1一个额外的参数,表示方法执行时的实例(this)作为第一个参数。

class Record {
BiFunction<MyClass, Integer, Integer> func = MyClass::f1;
}

class MyClass {
public int f1(int arg) {
return arg * arg;
}
int example(Record r, int arg) {
return r.func.apply(this, arg);
}
}

1 -实际上this参数已经在所有实例方法的字节码中(只是不需要声明它)。f1方法等价于public int f1(MyClass this, int arg)

您需要这些函数为static,或者您需要解释实例变量将来自何处。为了给你一个完整的例子,我不得不写Record。简而言之,你想要一个Function<Integer, Integer>,你想要apply它。类似的,

class Record {
private Pattern regex;
private Function<Integer, Integer> func;
public Record(Pattern p, Function<Integer, Integer> f) {
this.regex = p;
this.func = f;
}
void foo(String s, int arg) {
for (Record r : table) { // this.regex.matcher(s).matches() ?
if (r.regex.matcher(s).matches()) {
int result = r.func.apply(arg);
break;
}
}
}
static final Record[] table = {
new Record(Pattern.compile("regex1"), Record::f1),
new Record(Pattern.compile("regex2"), Record::f2)
};
public static int f1(int arg) {
return arg * arg;
}
public static int f2(int arg) {
return arg + arg;
}
}

最新更新