背景:
想写一个工具类 Tool.java ,其中方法 public void readOneLine() 负责一行一行地读文件,然后根据不同的业务,对每一行进行不同处理。最后输出到文件 out.txt
那么问题来了,根据不同的业务,进行不同处理 怎么实现?
自然而然想到,每个业务有一个对读取的一行的处理方法 public void 业务名(),我们把方法作为参数传入 public void readOneLine(业务名()),比如:
业务A:
readOneLine(直接输出每一行())
业务B:
readOneLine(每一行全部大写后输出())
业务C:
readOneLine(输出每一行的第一个单词())
......
很可惜,java 7不支持这样的语法,也许java 8 的 lambda 表达式可以?这不在今天讨论的范围里
java 7 要实现这样的功能需要通过回调函数
回调函数 - A类中调用B类中的某个方法methodB(),然后 methodB() 中反过来调用A类中的methodA()。methodA()这个方法就叫回调函数
一个同步回调函数的例子
回调函数接口,这个接口是必须的吗?
是。不仅为了符合面向接口编程的规范
事实上,调用方将会 Override 接口的 具体业务逻辑(),达到传函数给被调用方的目的。
//回调函数接口及方法
public interface 业务逻辑 {
public void 具体业务逻辑();
}
public class Tool {
private 业务逻辑 yewuluoji; //私有接口成员
public void setYewuluoji(业务逻辑 yewuluoji){
this.yewuluoji = yewuluoji;
}
public void 工具类逻辑() {
//读文件
while(每一行){
yewuluoji.具体业务逻辑();
}
}
}
测试类:
public class MainClass {
public MainClass() {
}
public static void main(String[] args) {
Tool tool = new Tool();
//传入 匿名实现类,包含具体业务逻辑
tool.setCallback(new 业务逻辑{
@Override
public void 具体业务逻辑() {
//输出每一行的第一个单词
}
});
tool.工具类逻辑(); //此方法中回调匿名类的具体业务逻辑(),即:输出每一行的第一个单词
}
}
java 8 lambda方式传函数(仅仅是语法糖?)
匿名类型最大的问题就在于其冗余的语法。有人戏称匿名类型导致了“高度问题”(height problem):比如前面ActionListener的例子里的五行代码中仅有一行在做实际工作。
lambda表达式是匿名方法,它提供了轻量级的语法(语法糖?),从而解决了匿名内部类带来的“高度问题”。
下面是一些lambda表达式:
(int x, int y) -> x + y
() -> 42
(String s) -> { System.out.println(s); }
lambda表达式的语法由参数列表、箭头->(等价于return)和函数体组成。函数体既可以是一个表达式,也可以是一个语句块:
lambda表达式也会经常出现在嵌套环境中,比如说作为方法的参数。为了使lambda表达式在这些场景下尽可能简洁,我们去除了不必要的分隔符。不过在某些情况下我们也可以把它分为多行,然后用括号包起来,就像其它普通表达式一样。
下面是一些出现在语句中的lambda表达式:
FileFilter java = (File f) -> f.getName().endsWith("*.java");
String user = doPrivileged(() -> System.getProperty("user.name"));
new Thread(() -> {
connectToService();
sendNotification();
}).start();