【问题标题】:How to define a function taking a Serializable lambda as parameter如何定义一个以 Serializable lambda 作为参数的函数
【发布时间】:2015-06-28 21:27:03
【问题描述】:

是否可以声明一个以 Serializable lambda 作为参数的方法,而无需声明专用接口或要求客户端 cast the lambda

让我们用这个玩具例子来说明我的问题:

 static <T, R> void serialize(Function<T, R> f) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
      oos.writeObject(f);
    }
  }

  public static void main(String[] args) throws IOException {
    serialize(e -> e);
  }

默认情况下,Lambda 是不可序列化的,并且会抛出预期的 NotSerializableException

为了让它工作,我们可以强制转换 lambda 以添加一个额外的 Serializable 绑定。

  static <T, R> void serialize(Function<T, R> f) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
      oos.writeObject(f);
    }
  }

  public static void main(String[] args) throws IOException {
    serialize((Function<Object, Object> & Serializable) e -> e);
  }

但是,这种解决方案令人不快,因为它强制每个调用者转换他们的 lambda,并且方法签名确实表明 f 必须是可序列化的。它冗长且容易出错。

要删除样板并使其类型安全,我们可以定义一个专用接口:

  interface SerFunction<T, R> extends Function<T, R>, Serializable { }

  static <T, R> void serialize(SerFunction<T, R> f) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
      oos.writeObject(f);
    }
  }

  public static void main(String[] args) throws IOException {
    serialize(e -> e);
  }

它完成了这项工作,几乎满足了我的需求。这种模式的唯一缺点是我必须在每个功能接口之上创建一个专用接口,这有点麻烦。是否可以使用额外的接口并直接在方法签名中声明多个边界?

【问题讨论】:

    标签: java serialization lambda


    【解决方案1】:

    我知道这个问题很老了,但由于它没有答案,我会试一试。

    但是,这种解决方案令人不快,因为它迫使每个调用者 转换他们的 lambda 并且方法签名确实表明 f 必须是 可序列化的。它冗长且容易出错。

    尽管此解决方案仍要求您声明您的 lambda 表达式也实现了 Serializable 接口,但这确实要求您这样做。

    所以,它在未实现时会出错。 它还允许在未实现 SerFunction 时使用 Function 的子级。

    public static <T, R, F extends Function<T, R> & Serializable> void serialize(F f) throws IOException
    {
        try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream()))
        {
            oos.writeObject(f);
        }
    }
    
    public static void main(String[] args) throws IOException
    {
        serialize((Function<Object, Object> & Serializable) e -> e);
        // all happy
    
        serialize((Function<Object, Object>) e -> e);
        // compiler error "no instance(s) of type variable(s) exist so that Function<Object, Object> conforms to Serializable
        // inference variable F has incompatible bounds:
        // lower bounds: Function<Object, Object>
        // upper bounds: Function<T, R>, Serializable"
    
    }
    

    【讨论】:

    • 当然,如果演员表是隐式的会更好,但仍然有用。
    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    相关资源
    最近更新 更多