Java8中BiConsumer传统实现报错:substring方法无法解析
关于Java8 BiConsumer传统实现的问题解答
首先明确说:@FunctionalInterface完全支持传统的类实现方式,你的问题肯定是代码细节上出了错,和这个注解本身没关系。
先给你看一段正确的传统方式实现BiConsumer的代码,对比下你自己的写法:
import java.util.function.BiConsumer; public class BiConsumerTest { // 假设你的method1是这样接收BiConsumer参数的 static void method1(String name, Integer count, BiConsumer<String, Integer> consumer) { consumer.accept(name, count); } static void test1(String name, Integer count) { // Lambda方式,正常运行 method1(name, count, (n, c) -> System.out.println(n.substring(0, c))); } static void test2(String name, Integer count) { // 方法引用方式,正常运行 method1(name, count, BiConsumerTest::printSubstring); } // test3用传统类实现BiConsumer static void test3(String name, Integer count) { method1(name, count, new MyBiConsumer()); } // 自定义BiConsumer实现类 static class MyBiConsumer implements BiConsumer<String, Integer> { @Override public void accept(String str, Integer count) { // 这里str是String类型,substring方法完全可以正常调用 if (count <= str.length()) { System.out.println(str.substring(0, count)); } else { System.out.println(str); } } } // 用于test2的方法引用 static void printSubstring(String str, Integer count) { System.out.println(str.substring(0, count)); } public static void main(String[] args) { test1("Hello", 3); test2("World", 2); test3("Java8", 4); } }
你出现str.substring无法解析的问题,大概率是下面这些原因之一:
- 没指定泛型参数:比如你的实现类写成了
implements BiConsumer而不是implements BiConsumer<String, Integer>,这时候accept方法的参数会默认是Object类型,直接调用substring当然会报错,因为Object没有这个方法。 - 变量名或类型写错:比如把参数名写成了
o而不是你以为的str,或者强转类型出错,比如没把Object转成String就调用方法。 - 参数顺序搞反了:比如把Integer参数当成了第一个参数,String当成第二个,这时候调用substring的是Integer类型,自然也会报错。
总结下:@FunctionalInterface只是用来标记接口符合函数式接口的规范(只有一个抽象方法),它不会限制你用任何方式实现这个接口——Lambda、方法引用、传统类实现都是完全支持的。你的问题就是代码里的类型匹配或者泛型声明出了问题,检查下test3对应的实现类代码就能找到问题啦。
内容的提问来源于stack exchange,提问作者user2761895
相关产品推荐
相关产品推荐

