Java序列化方法

时间:2011-02-07 08:18:17

标签: java serialization reflection

可以序列化方法吗?因为当我查看文档时,Method类不实现Serializable。那么还有其他选择吗?

7 个答案:

答案 0 :(得分:10)

由于Method没有实现Serializable,因此无法使用标准Java Serialization API对其进行序列化。

解决方法是手动序列化类和方法的名称及其参数类型。然后,您可以在反序列化期间重新创建Method实例。

答案 1 :(得分:7)

这取决于你的意思。 真的,正如人们已经提到的方法无法序列化。但是,如果您希望序列化方法实现的逻辑并且(例如)通过网络发送它,则可以。这种序列化可以通过序列化类本身来完成。实际上.class已经是一个可以存储(并且通常存储)在文件中的字节序列。您可以根据需要通过网络发送它,然后使用Class.forName()进行实例化。此外,您可以做得更好:使用HttpClassLoader,将您的类可用的HTTP URL传递给它,使用此类加载器创建类实例并运行您想要的任何方法。

答案 2 :(得分:4)

您可以使用以下包装器来允许方法序列化:

public class SerializableMethod implements Serializable
{
    private static final long serialVersionUID = 6631604036553063657L;
    private Method method;

    public SerializableMethod(Method method)
    {
        this.method = method;
    }

    public Method getMethod()
    {
        return method;
    }

    private void writeObject(ObjectOutputStream out) throws IOException
    {
        out.writeObject(method.getDeclaringClass());
        out.writeUTF(method.getName());
        out.writeObject(method.getParameterTypes());
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
        Class<?> declaringClass = (Class<?>)in.readObject();
        String methodName = in.readUTF();
        Class<?>[] parameterTypes = (Class<?>[])in.readObject();
        try
        {
            method = declaringClass.getMethod(methodName, parameterTypes);
        }
        catch (Exception e)
        {
            throw new IOException(String.format("Error occurred resolving deserialized method '%s.%s'", declaringClass.getSimpleName(), methodName), e);
        }
    }
}

答案 3 :(得分:1)

如果你只是想知道,是否可能,而不是:它没有实现Serializable。此外,Method是最终类,因此您无法将其子类化以添加某些功能。

答案 4 :(得分:1)

实际上,所有方法都是其类的一部分,而Class 确实实现了Serializable。因为无论如何你都需要类的对象来调用方法,你可以发送类(或对象)。

但是,在接收方,通常会在那里创建一个类版本的对象。

如果你想使用它在远程端调用你的方法,看看RMI(包java.rmi.*) - 它还支持当远程端(还)没有类时发送对象数据

答案 5 :(得分:0)

Thought Works图书馆xStream做得非常好。这是两分钟tutorial

答案 6 :(得分:0)

Python允许pickling顶级方法,在Java中,通过某种RMI机制调用另一台主机上的方法。类字节码可以通过线路发送,并且满足所有依赖性 - 使用URLClassloader来执行此操作。