一些编程语言通过提供函数指针、委托、lambda
表达式或者其他类似的方式,来使得程序拥有存储、并传递特殊函数的能力。Java
没有提供函数指针,但是对象引用能提供相同的效果,另Java 1.8
开始,提供了lambda
表达式。
例如,针对字符串的比较,假设我们定义一个比较:
class StringLengthCompare {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
但是对于调用此比较的方法来说,也许它还需要调用其他字符串比较,那我们最好让比较实现某个接口。这样调用的方法中参数类型只需指定为接口类型即可。譬如:
class StringLengthCompare implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
当需要调用比较对象(函数指针)的时候,如果只是单次调用,那么我们可以采用匿名类的形式调用,譬如:
Collections.sort(list, new Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
但是如果是需要重复调用此比较对象,那么最好为此提供实例,避免创建多余的对象:
clas Host {
private static class StringLengthCompare implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
public static final Comparator<String> STRING_LENGTH_COMPARE = new StringLengthCompare();
//之后可以多次调用STRING_LENGTH_COMPARE对象
}
总之,函数指针的主要作用就是实现策略模式。为了实现此模式,你可以先定义个接口,之后实现接口以实现不同的具体策略。如果此策略只使用一次,采用匿名类即可;如果需要使用多次,则可以将策略作为宿主类(如上面例子中的Host
类)的静态内部类,并创建静态实例供多次调用。