2011-02-07 20 views
14

¿Es posible serializar un método? Porque cuando miro la documentación, la clase Method no implementa Serializable. Entonces, ¿hay alguna alternativa?Java Serializing Methods

+6

¿Qué estás tratando de hacer? ¿Serializar el bytecode? – EboMike

+0

no es como que solo estoy pensando si es posible porque tengo otra pregunta si estoy seguro de que es posible –

+1

Eso todavía no responde mi pregunta. ¿Está intentando serializar el bytecode, es decir, está tratando de tomar un método completo y ponerlo en una secuencia, o simplemente está intentando serializar los datos lógicos, es decir, el paquete, el nombre del método y los tipos de argumentos? – EboMike

Respuesta

9

Dado que Method no implementa Serializable, no se puede serializar utilizando la API de serialización Java estándar.

Una solución alternativa sería serializar manualmente solo el nombre de la clase y el método y sus tipos de parámetros. Luego puede volver a crear la instancia del Método durante la deserialización.

1

Si solo te preguntas, ¿es posible? Que no: no implementa Serializable. Además, Method es una clase final, por lo que no puede crear una subclase para agregar alguna funcionalidad.

6

Depende de lo que signifique. Realmente, como los chicos que ya se mencionó, el método no se puede serializar. Pero si desea serializar la lógica que implementa el método y (por ejemplo) enviarla a través de la red, es posible. Esta serialización se puede hacer mediante la serialización de la clase en sí. En realidad, .class ya es una secuencia de bytes que se puede almacenar (y, por lo general, se almacena) en archivos. Puede enviarlo a través de la red si lo desea y luego crear una instancia utilizando Class.forName(). Además, puedes hacerlo mejor: utiliza HttpClassLoader, pasale la URL HTTP donde tu clase está disponible, crea una instancia de clase usando este cargador de clases y ejecuta cualquier método que desees.

+2

enviar una clase a través de la red es más complicado que enviar los bytes y luego llamar a class.forname(). class.forname() solo carga una clase que ya está en classpath. primero tendría que hacer esos bytes disponibles en la ruta de clase de alguna manera. – jtahlborn

+0

Usted dijo: "Pero si desea serializar la lógica que implementa el método y (por ejemplo) enviarla a través de la red, es posible. Esta serialización se puede hacer mediante la serialización de la clase. En realidad, la clase ya es una secuencia de bytes que puede ser almacenado (y típicamente almacenado) en archivos ". ¿Quieres decir que puedo serializar las implementaciones de métodos? Si eso es posible, ¿también es posible serializar los métodos anulados a través de declaraciones de clases anónimas? –

0

Thought Works biblioteca xStream lo hace muy bien. Aquí hay dos minutos tutorial.

+0

Lo sentimos, no hay nada acerca de la serialización de 'Methods' allí –

+1

Simplemente pase una instancia de Method al xerma XML serializer y obtendrá la serialización. –

0

Python no permite pickling de los métodos de nivel superior, en Java la forma de llamar a los métodos en otro host es a través de algún tipo de mecanismos de RMI. El bytecode de clase se puede enviar por cable y, dado que todas las dependencias están satisfechas, use URLClassloader para hacer esto.

1

En realidad, todos los métodos son parte de su clase, y Classhace implementar Serializable. Ya que necesitarás un objeto de la clase para llamar al método, puedes enviar la clase (o el objeto).

En el lado receptor, sin embargo, generalmente se crearía un objeto de la versión de la clase allí.

Si desea utilizar esto para invocar su método en un lado remoto, eche un vistazo a RMI (paquete java.rmi.*) - admite también el envío de objetos cuando el lado remoto aún no tiene los datos de clase.

4

se puede utilizar el siguiente método de envoltura para permitir serialiation:

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); 
     } 
    } 
}