Runnable对象不能直接序列化传输,因其是行为契约而非数据载体,且匿名类、Lambda或非静态内部类常隐式持有不可序列化资源(如连接、外部类引用等),触发NotSerializableException。
Java中实现Runnable接口的多线程对象**不能直接序列化传输**,核心原因在于:Runnable本身不是数据载体,而是行为契约;而绝大多数实际实现(尤其是匿名类、Lambda、非静态内部类)会隐式持有不可序列化资源,触发NotSerializableException。
Java原生序列化要求对象图中所有非transient、非static字段类型都必须实现Serializable。但Runnable实现常含以下不可序列化成分:
ExecutorService、Logger、Socket、数据库连接等),这些对象本身不可序列化this$0),若外部类未实现Serializable,反序列化时立即失败static非transient字段,且类型不可序列化(如ThreadLocal、ConcurrentHashMap某些场景下的value),也会中断序列化流程仅当满足全部条件时,Runnable实例才可能被序列化:
public static class定义(切断对外部类的隐式引用)private static final long serialVersionUID = 1L;
TaskRequest)不序列化Runnable本身,而是序列化它的“描述”:
立即学习“Java免费学习笔记(深入)”;
TaskRequest),只包含taskId、params、timeout等可序列化字段executor.submit(() -> process(request)))若业务强依赖序列化子类Runnable(不推荐),可加防护:
private void readObject(ObjectInputStream in) throws IOException { throw new InvalidClassException("Not deserializable"); }
serialVersionUID,否则该方法不会被调用