从Consumer#andThen()返回可序列化的消费者

时间:2016-03-12 16:08:19

标签: java serialization lambda java-8

我知道要使Java 8 Consumer可序列化,我必须强制转换它:

return (Consumer<Type> & Serializable) () -> {...}

工作正常。

为了更容易,我已经介绍了我自己的SerializableConsumer,它实现了java.io.Serializable并在我的API中使用它:

private interface SerializableConsumer<T> extends Consumer<T>, Serializable {}

现在我希望每当有人使用SerializableConsumer#andThen()再次返回可序列化的消费者时 这是我的尝试,但到目前为止,我无法使它工作。欢迎任何想法!

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.function.Consumer;

public class SerializeLambdas {

    private interface SerializableConsumer<T> extends Consumer<T>, Serializable {}

    // attempt 1
    private interface SerializableConsumerAndThen<T> extends Consumer<T>, Serializable {
        @Override
        default SerializableConsumerAndThen<T> andThen(Consumer<? super T> after) {
            return (SerializableConsumerAndThen<T>) Consumer.super.andThen(after);
        }
    }

    // attempt 2
    private interface SerializableConsumerAndThen2<T> extends Consumer<T>, Serializable {
        @Override
        default Consumer<T> andThen(Consumer<? super T> after) {
             return (Consumer<T> & Serializable) (T t) -> { accept(t); after.accept(t); };
        }
    }

    private static <T> T serializeCopy(T t) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(t);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (T) ois.readObject();
    }

    public static void main(String[] args) throws Exception {
        // this works!
        SerializableConsumer<String> consumer = (s) -> System.out.println(s);
        SerializableConsumer<String> copy = serializeCopy(consumer);
        copy.accept("It works!");


        // this doesn't work
        SerializableConsumerAndThen<String> consumer2 = (s) -> System.out.println(s);
        Consumer<String> consumerAndThen = consumer2.andThen((s2) -> System.out.println(s2));
        Consumer<String> copy2 = serializeCopy(consumerAndThen);
        copy2.accept("SerializableConsumerAndThen works!");


        // this doesn't work too
        SerializableConsumerAndThen2<String> consumer3 = (s) -> System.out.println(s);
        Consumer<String> consumerAndThen2 = consumer3.andThen((s2) -> System.out.println(s2));
        Consumer<String> copy3 = serializeCopy(consumerAndThen2);
        copy3.accept("SerializableConsumerAndThen2 works!");
    }
 }

两者都失败了:

Exception in thread "main" java.lang.ClassCastException: java.util.function.Consumer$$Lambda$5/1334729950 cannot be cast to app.SerializeLambdas$SerializableConsumerAndThen
at app.SerializeLambdas$SerializableConsumerAndThen.andThen(SerializeLambdas.java:17)
at app.SerializeLambdas.main(SerializeLambdas.java:46)
....

0 个答案:

没有答案