有时候看到 new 类().{方法定义}.方法 这种怪异的代码,是匿名内部类的用法。
public class practice {
public static void main(String[] args) {
flatMap(new FlatMapFunction() {
@Override
public void call() {
System.out.println("spark接口就是这么调用的");
}
});
}
static void flatMap(FlatMapFunction tf) {
tf.call();
}
}
interface FlatMapFunction {
void call();
}
要使用接口,就必须实现接口的方法再调用方法。
匿名内部类语法,允许我们不需要单独定义接口,而是在main方法中来实现这个过程。这使得接口实现的修改像if和for一样随意了,比如spark中的一些接口的重载方法。
所谓“内部”是指在方法内调用,”匿名”是指没有给接口的实现类具体命名。
再看看spark的java版本算子,就是用到了匿名内部类,对于没有接触过匿名内部类的人,一定搞得云里雾里。
public class FlatMapOperator {
public static void main(String[] args){
SparkConf conf = new SparkConf().setMaster("local").setAppName("flatmap");
JavaSparkContext sc = new JavaSparkContext(conf);
List<String> list = Arrays.asList("w1 1","w2 2","w3 3","w4 4");
JavaRDD<String> listRdd = sc.parallelize(list);
JavaRDD<String> result = listRdd.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterator<String> call(String s) throws Exception {
return Arrays.asList(s.split(" ")).iterator();
}
});
result.foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.err.println(s);
}
});
}
}
FlatMapFunction是内部匿名类的声明,<String, String> 是接口的模板,call是重载的接口方法。