我想要一个这样的表格:
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;
}
}