java - 如何阻止功能接口(interface)成为 lambda 表达式的目标?

标签 java lambda functional-interface

我有一个 API,其接口(interface)具有两个(重载的)同名方法,它们采用不同的参数类型。这些不同类型都是技术上的功能接口(interface),但不应允许用户创建其中之一的实例。这是一个简化的示例:

public class Example
{
    @FunctionalInterface
    public interface Computation
    {
        int compute();
    }

    public interface WrappedComputation
    {
        Computation unwrap();
    }

    public static class Solver
    {
        public static int solve(Computation a)
        {
            return a.compute();
        }

        public static int solve(WrappedComputation b)
        {
            return solve(b.unwrap());
        }
    }

    public static void main(String... args)
    {
        // 'Computation' interface should be a lambda target
        // so coder can make their own 'A' computation
        Solver.solve( () -> { return 5 + 5; } );

        // 'WrappedComputation' interface SHOULD NOT be a lambda target
        // or else coder can cause runtime exceptions etc., like passing a null 'Computation' reference that will be computed
        Solver.solve( () -> { Computation a = null; return a; } );
    }
}

到目前为止,我唯一的想法是向我不想成为 lambda 目标的接口(interface)添加一个虚拟/未使用的方法,并在所有实现类中实现它。这似乎有点草率/不需要……还有其他建议吗?

最佳答案

当您的接口(interface)满足 the criteria 时,无法阻止 API 客户端使用 lambda 表达式

您认为 API 客户端只能通过 lambda 引起麻烦的假设是不正确的——您可以用 lambda 做的任何坏事,您也可以用匿名内部类或命名类做。考虑:

Solver.solve( new WrappedComputation(){
    public Computation unwrap(){
        Computation a = null; return a;
    }
});

这与您的 lambda 具有完全相同的语义和最终结果(运行时异常)。

也许您想要的是防止 任何 不受控制地创建 WrappedComputation?在这种情况下,请考虑将其设为 final 类,其构造函数会检查错误情况:

public final class WrappedComputation{
    private final Computation _wrapped;
    public WrappedComputation(@NonNull wrapped){
        _wrapped = Objects.requireNonNull(wrapped);
    }
}

关于java - 如何阻止功能接口(interface)成为 lambda 表达式的目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45778003/

相关文章:

java - 存储整数集以检查某个集合是否已被提及

java - 计算 H2 数据库引擎中表中的条目数

C# IS 运算符不能用于 lambda 表达式?

python - 在这种情况下,这个功能到底做了什么?

java - 使用Callable代替Supplier,反之亦然

java - 构建后生成的目标文件不包含必须存在的所有已编译类

java - 使用 AWS SDK for Java 版本 2 进行 SNS 验证

java - 是否可以在 Java 8 中使用对象的特定方法(或静态方法)作为仿函数

c# - LINQ to Entities : Using DateTime. Lambda 表达式中的 AddMonth

java - 从 Function<V, R> 使用 compose() 或 andThen() 时返回对象