Lambda表达式仅适用于函数式接口(有且仅一个抽象方法),如Runnable、Comparator;非函数式接口(如WindowAdapter)不可用。它简化匿名内部类,省略模板代码,聚焦“参数→动作”,支持参数和体的灵活省略,但需遵守“事实final”变量限制,复杂逻辑应优先使用命名方法。
Lambda 表达式不是“所有匿名内部类的通用替身”,而是专为
函数式接口
设计的语法糖——它只在接口有且仅有一个抽象方法时生效。理解这一点,是避免编译错误和误用的关键。
核心前提:必须是函数式接口
函数式接口指
只有一个抽象方法
的接口(可以有默认方法、静态方法或重写 Object 的方法)。Java 用
注解来标识并强制校验。例如:
:只有
:只有
:只有
不行——它有 7 个抽象方法,不能用 Lambda 替代
简化逻辑:去掉模板,聚焦行为
匿名内部类本质是“定义一个一次性类 + 实例化”,而 Lambda 直接表达“我要执行什么”。对比来看:
传统写法:
立即学习
“
Java免费学习笔记(深入)
”;
new Thread(new Runnable() {public void run() {System.out.println("Hello");}});
Lambda 写法:
new Thread(() -> System.out.println("Hello"));
省去了:
类名、方法声明、return 关键字(无返回值时)、new 和大括号嵌套
,只保留“参数 → 动作”这一核心关系。
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
参数与体的灵活省略规则
Lambda 支持按需精简,IDE 通常能自动推导类型:
无参:用
,如
单参:可省括号,如
或
单句表达式:省大括号和分号,如
多句逻辑:必须用大括号 + 分号,如
注意捕获变量的“事实 final”限制
Lambda 只能访问
未被重新赋值的局部变量
(即“事实 final”),因为 JVM 实际捕获的是变量值的副本,而非引用。例如:
int count = 0;list.forEach(x -> count++); // 编译报错
若需修改外部状态,推荐方式是:
改用原子类:
或换思路:用
等无副作用操作替代
不是越短越好:该用还是该写命名方法?
简洁不等于合适。以下情况建议放弃 Lambda:
逻辑超过 3 行,或含 if/else、try/catch 等复杂控制流
需要复用、打条件断点、加日志追踪调试
性能敏感场景(如高频创建短生命周期对象),Lambda 可能带来额外 invokedynamic 开销
此时更清晰的做法是:写一个私有方法,再用方法引用,如
。
@FunctionalInterfaceRunnablerun()ActionListeneractionPerformed()Comparatorcompare()WindowAdapter()() -> doSomething()e -> handle(e)(ActionEvent e) -> handle(e)(a, b) -> a.compareTo(b)(x, y) -> { log(x); return x + y; }AtomicInteger count = new AtomicInteger(); list.forEach(x -> count.incrementAndGet());stream().reduce()list.forEach(this::processItem)