特定对象的实例方法引用语法为对象名::实例方法名,要求函数式接口抽象方法与实例方法的参数列表和返回值完全匹配,如"hi"::startswith等价于s->"hi".startswith(s)。

当你已经有一个具体对象,想用它的某个实例方法来代替函数式接口的抽象方法时,就用“特定对象的实例方法引用”,语法是 对象名::实例方法名。
适用前提:函数式接口的抽象方法参数列表和返回值,要和该对象的实例方法完全匹配
比如,假设你有:
- 一个字符串对象 str = "Hello"
- 函数式接口(如 Predicate
)的抽象方法是 boolean test(String s) - 而 str.startsWith(String) 方法签名正好是 boolean startsWith(String prefix),参数类型、数量、返回值都一致
那就可以写成:str::startsWith,它等价于 s -> str.startsWith(s)。
常见使用场景举例
1. 判断字符串是否以某前缀开头
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Predicate<string> startsWithHi = "Hi"::startsWith;
System.out.println(startsWithHi.test("Hello")); // false
System.out.println(startsWithHi.test("Hi there")); // true
</string>
2. 调用已有集合的 contains 方法做过滤
List<string> allowed = Arrays.asList("apple", "banana", "cherry");
Predicate<string> isInAllowed = allowed::contains;
List<string> input = Arrays.asList("apple", "dog", "banana");
input.stream().filter(isInAllowed).forEach(System.out::println); // apple, banana
</string></string></string>
3. 使用已创建的工具对象的方法(比如自定义格式器)
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
Function<localdate string> format = formatter::format;
System.out.println(format.apply(LocalDate.now())); // 如:2024-06-15
</localdate>
注意点
- 被引用的方法必须是**实例方法**,不能是静态方法(静态方法用 类名::静态方法名)
- 对象在方法引用创建时必须**已存在且非 null**,否则运行时调用会抛 NullPointerException
- 方法引用本身不执行方法,只是“绑定”了对象和方法;真正执行发生在函数式接口被调用时(如 predicate.test(...))
- 如果目标方法是重载的,编译器根据函数式接口的抽象方法签名自动选择,如有歧义需显式转型或改用 Lambda
对比 Lambda 更简洁,但前提是对象已就位
写 str::toLowerCase 比写 s -> str.toLowerCase() 少了参数和箭头,也更直观——明确表达“用这个 str 做 toLowerCase”。但如果你还没创建 str,或者每次要用不同对象,那就得用 Lambda 或换用“任意对象的实例方法引用”(String::toLowerCase)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










