Java 8自定义BiSupplier函数式接口报错:存在多个非重写抽象方法求助
BiSupplier Interface Throws an Error Hey there! Let's break down exactly why you're hitting that "Multiple non-overriding abstract methods found in BiSupplier" error.
First, a quick reminder: the @FunctionalInterface annotation has a strict rule—it can only be applied to interfaces that have exactly one abstract method (methods inherited from Object like equals() or toString() don't count). Your current BiSupplier has two abstract methods (getFirst() and getSecond()), which directly breaks this rule. That's the root cause of the compiler complaint.
Why There's No Built-in BiSupplier in the JDK
The core purpose of a Supplier is to provide a single value. When you need to return two values, Java's standard approach is to wrap those values into a single container object instead of having separate "get" methods. This aligns with the functional interface contract and keeps the design consistent with other functional types like BiFunction (which takes two inputs and returns one output).
Fixing Your Code
You have two straightforward solutions here:
Option 1: Rewrite the Interface to Return a Composite Object
Adjust your BiSupplier to return a single object that holds both values. This lets you keep the @FunctionalInterface annotation and use lambdas with it. You can use a Java 16+ record (cleanest option), a custom POJO, or even a built-in type like Map.Entry:
// Define a record to hold your two values (Java 16+) public record Pair<T, R>(T first, R second) {} // Now your functional interface has exactly one abstract method @FunctionalInterface public interface BiSupplier<T, R> { /** * Gets a pair containing both values. * * @return a Pair with the first and second value */ Pair<T, R> get(); } // Usage example with lambda BiSupplier<String, Integer> supplier = () -> new Pair<>("Alice", 30); Pair<String, Integer> result = supplier.get(); System.out.println(result.first()); // Prints "Alice" System.out.println(result.second()); // Prints 30
If you're on a Java version before 16, replace the record with a simple POJO:
public class Pair<T, R> { private final T first; private final R second; public Pair(T first, R second) { this.first = first; this.second = second; } // Getters public T getFirst() { return first; } public R getSecond() { return second; } }
Option 2: Remove the @FunctionalInterface Annotation
If you really want to keep two separate get methods, you can't use @FunctionalInterface—this turns it into a regular interface. You'll have to implement it with an anonymous inner class or concrete class, though you won't be able to use lambdas with it:
// No @FunctionalInterface annotation here public interface BiSupplier<T, R> { T getFirst(); R getSecond(); } // Usage with anonymous inner class BiSupplier<String, Integer> supplier = new BiSupplier<>() { @Override public String getFirst() { return "Bob"; } @Override public Integer getSecond() { return 25; } };
Key Takeaway
Functional interfaces exist to support lambda expressions, which depend on having a single abstract method for the compiler to infer the implementation. If you need to return multiple values, wrapping them into a single object is the idiomatic Java approach.
内容的提问来源于stack exchange,提问作者Alex Man

