2011-02-07 4 views
14

Можно сериализовать метод? Потому что, когда я смотрю документацию, класс Method не реализует Serializable. Есть ли альтернативы?Java Serializing Methods

+6

Что вы пытаетесь сделать? Сериализовать байт-код ?! – EboMike

+0

Не похоже, что я просто размышляю, если это возможно, потому что у меня есть другой вопрос, если я уверен, что это возможно. –

+1

Это все еще не отвечает на мой вопрос. Вы пытаетесь выполнить сериализацию байт-кода, т. Е. Вы пытаетесь использовать весь метод и помещать его в поток, или просто пытаетесь выполнить сериализацию логических данных, то есть имя пакета, метода и типы аргументов? – EboMike

ответ

9

Поскольку метод не реализует Serializable, его нельзя сериализовать, используя стандартный Java Serialization API.

Обходным путем было бы вручную сериализовать только имя класса и метода и его типы параметров. Затем вы можете воссоздать экземпляр Method во время десериализации.

1

Если вам просто интересно, возможно, чем нет: он не реализует Serializable. Кроме того, Method - это последний класс, поэтому вы не можете подклассифицировать его, чтобы добавить некоторые функции.

6

Это зависит от того, что вы имеете в виду. Действительно, поскольку ребята, упомянутые выше, не могут быть сериализованы. Но если вы хотите сериализовать логику, которую реализует этот метод, и (например) отправить ее по сети, это возможно. Эта сериализация может быть выполнена путем сериализации самого класса. Фактически .class - это уже последовательность байтов, которые могут быть сохранены (и, как правило, сохранены) в файлах. Вы можете просто отправить его по сети, если хотите, а затем создать экземпляр, используя Class.forName(). Кроме того, вы можете сделать лучше: используйте HttpClassLoader, передайте ему URL-адрес HTTP, где доступен ваш класс, создайте экземпляр класса с помощью этого загрузчика классов и запустите любой метод, который вы хотите.

+2

отправка класса по сети сложнее, чем отправка байтов, а затем вызов класса.forname(). class.forname() загружает только класс уже в пути к классам. вам сначала нужно сделать эти байты доступными на пути к классам. – jtahlborn

+0

Вы сказали: «Но если вы хотите сериализовать логику, реализующую этот метод, и (например) отправить ее по сети, это возможно. Эта сериализация может быть выполнена путем сериализации самого класса. Фактически .class - это уже последовательность байтов, которая может хранить (и, как правило, хранить) в файлах ». Вы имеете в виду, что я могу сериализовать реализации методов? Если это возможно, возможно ли также переопределять методы сериализации через объявления анонимных классов? –

0

Thought Works библиотека xStream Очень хорошо. Вот две минуты: tutorial.

+0

Извините, нет ничего о сериализации 'Методы' там –

+1

Просто передайте экземпляр Method в XML-сериализатор xStream, и вы получите сериализацию. –

0

Python действительно позволяет pickling методов верхнего уровня, в Java способ вызова методов на другом хосте через какие-то механизмы RMI. Байт-код класса может быть отправлен по проводу и заданы все зависимости. Для этого используйте URLClassloader.

1

На самом деле, все методы являются частью их класса, а Classделает реализовать Serializable. Так как вам понадобится объект класса, чтобы вызвать метод, вы можете просто отправить класс (или объект).

На стороне приема, однако, обычно там будет создан объект версии класса.

Если вы хотите использовать это для вызова своего метода на удаленной стороне, взгляните на RMI (пакет java.rmi.*) - он также поддерживает отправку объектов, когда удаленная сторона еще не имеет данные класса.

4

вы можете использовать следующую обертку, чтобы метод 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); 
     } 
    } 
}