java方法引用分限定型(对象::方法,需已有实例)和非限定型(类名::方法,首个参数作接收者),选择依据是函数式接口参数结构决定调用对象来源。

Java 中方法引用的编写关键在于区分“限定型”和“非限定型”实例方法引用——核心区别是:是否已存在目标对象实例。
限定型实例方法引用(有明确调用对象)
语法为 对象名::实例方法名,适用于已有具体对象、且该对象能直接调用目标方法的场景。编译器知道调用者是谁,因此不需推断接收者。
- 必须是已创建的对象(不能是 new 表达式或未初始化变量)
- 方法签名需与函数式接口抽象方法兼容(参数数量、类型、返回值匹配)
- 例如:str::length(
str是 String 实例),对应Supplier<integer></integer> - 常见用途:将已有对象的某个行为封装为函数式接口实现
非限定型实例方法引用(无具体对象,依赖上下文提供)
语法为 类名::实例方法名,编译器会把函数式接口的第一个参数视为隐式调用对象(即“接收者”)。它本质上是“待绑定”的方法模板。
- 要求函数式接口抽象方法至少有一个参数,且第一个参数类型与方法所属类一致
- 例如:String::length 对应
Function<string integer></string>(第一个参数String就是调用length()的对象) - 再如:String::startsWith 对应
BiFunction<string string boolean></string>(第一个参数是调用者,第二个是入参) - 不能用于无参实例方法(除非函数式接口也无参,但此时无法提供接收者,故不合法)
容易出错的边界情况
并非所有写法都合法,需严格满足类型推导规则:
-
List::size ❌ 不合法 ——
List是接口,不能直接调用实例方法;且无具体对象,又不是静态方法,编译失败 - new ArrayList()::size ✅ 合法 —— 属于限定型(有明确对象)
-
ArrayList::size ❌ 不合法 ——
size()是实例方法,但ArrayList类型本身不能作为调用者;非限定型只接受“类名::方法”,且要求方法属于该类或其父类,但此处上下文无法提供接收者实例 - 若需类似效果,应写成 list -> list.size() 或使用 Collection::size(前提是函数式接口形参类型为
Collection)
选择依据:看函数式接口的参数结构
决定用限定型还是非限定型,本质是看“谁来调用这个方法”:
- 如果调用对象已经存在 → 用 对象::方法
- 如果调用对象由函数式接口的参数提供 → 用 类名::方法
- 静态方法始终用 类名::静态方法(不属于实例引用范畴)
- 构造方法用 类名::new(特殊形式,也属方法引用)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











