Сериализация Java с не сериализуемые части

Я решил FastClasspathScanner решить эту проблему. Он обрабатывает много разных типов задач сканирования классов, имеет простой API, работает со многими различными классами ClassLoaders и classpath, тщательно распараллелен и оптимизирован для высокоскоростного и низкого потребления памяти. Он может даже генерировать визуализацию GraphViz графа классов, показывая, как классы связаны друг с другом.

Для вашего первоначального вопроса о поиске всех классов или интерфейсов в данном пакете вы можете сделать:

List classNames = new FastClasspathScanner("com.mypackage").scan()
    .getNamesOfAllClasses();

Существует много возможных вариантов: см. документацию (см. выше) для полной информации.

52
задан Burkhard 18 September 2008 в 18:15
поделиться

9 ответов

Как кто-то еще отметил, глава 11 Josh Bloch , Эффективный Java является необходимым ресурсом на Сериализации Java.

Пара точек из той главы, подходящей для Вашего вопроса:

  • принятие Вы хотите сериализировать состояние несериализуемого поля в MyClass2, то поле должно быть доступно для MyClass, или непосредственно или через методов get и методы set. MyClass должен будет реализовать пользовательскую сериализацию путем обеспечения readObject и writeObject методы.
  • Класс несериализуемого поля должен иметь API, чтобы позволить добираться, это - состояние (для записи в объектный поток) и затем инстанцирование нового экземпляра с тем состоянием (при позже чтении из объектного потока.)
  • на Объект 74 из Эффективного Java, MyClass2 должен иметь конструктора без аргументов, доступного для MyClass, иначе для MyClass невозможно расширить MyClass2 и сериализуемую реализацию.

я записал быстрый пример ниже иллюстрирования этого.


class MyClass extends MyClass2 implements Serializable{

  public MyClass(int quantity) {
    setNonSerializableProperty(new NonSerializableClass(quantity));
  }

  private void writeObject(java.io.ObjectOutputStream out)
  throws IOException{
    // note, here we don't need out.defaultWriteObject(); because
    // MyClass has no other state to serialize
    out.writeInt(super.getNonSerializableProperty().getQuantity());
  }

  private void readObject(java.io.ObjectInputStream in)
  throws IOException {
    // note, here we don't need in.defaultReadObject();
    // because MyClass has no other state to deserialize
    super.setNonSerializableProperty(new NonSerializableClass(in.readInt()));
  }
}

/* this class must have no-arg constructor accessible to MyClass */
class MyClass2 {

  /* this property must be gettable/settable by MyClass.  It cannot be final, therefore. */
  private NonSerializableClass nonSerializableProperty;

  public void setNonSerializableProperty(NonSerializableClass nonSerializableProperty) {
    this.nonSerializableProperty = nonSerializableProperty;
  }

  public NonSerializableClass getNonSerializableProperty() {
    return nonSerializableProperty;
  }
}

class NonSerializableClass{

  private final int quantity;

  public NonSerializableClass(int quantity){
    this.quantity = quantity;
  }

  public int getQuantity() {
    return quantity;
  }
}
49
ответ дан Scott Bale 7 November 2019 в 19:08
поделиться

Если можно изменить MyClass2, самый легкий способ обратиться, это, объявляют переходный процесс свойства.

11
ответ дан ykaganovich 7 November 2019 в 19:08
поделиться

MyClass2 является просто интерфейсом так techinicaly, он не имеет никаких свойств, только методы. Это сказанное, если у Вас есть переменные экземпляра, которые самостоятельно не serializeable единственный способ, которым я знаю об обойти его, должно объявить те поля переходный процесс.

исключая:

private transient Foo foo;

, Когда Вы объявите полевой переходный процесс, это будет проигнорировано во время процесса сериализации и десериализации. Следует иметь в виду, что при десериализации объекта с переходным полем, которым всегда будет значение поля, это - значение по умолчанию (обычно пустой указатель.)

Примечание можно также переопределить readResolve () метод класса для инициализации переходных полей на основе другого состояния системы.

35
ответ дан Mike Deck 7 November 2019 в 19:08
поделиться

Зависит, почему тот член MyClass2 не является сериализуемым.

, Если существует некоторое серьезное основание, почему MyClass2 не может быть представлен в сериализированной форме, тогда возможности хороши, та же причина относится к MyClass, так как это - подкласс.

может быть возможно записать пользовательскую сериализированную форму для MyClass путем реализации readObject и writeObject таким способом, которым состояние данных экземпляра MyClass2 в MyClass может быть соответственно воссоздано от сериализированных данных. Это было бы способом пойти, если API MyClass2 фиксируется, и Вы не можете добавить сериализуемый.

, Но сначала необходимо выяснить, почему MyClass2 не является сериализуемым, и, возможно, измените его.

5
ответ дан Steve Jessop 7 November 2019 в 19:08
поделиться

Необходимо будет реализовать writeObject() и readObject() и сделать ручную сериализацию/десериализацию тех полей. Посмотрите javadoc страницу для java.io.Serializable для деталей. У Josh Bloch Эффективный Java также есть некоторые хорошие главы по реализации устойчивой и безопасной сериализации.

6
ответ дан jediz 7 November 2019 в 19:08
поделиться

Несколько возможностей появились, и я возобновляю их здесь:

  • Реализация writeObject () и readObject () как sk предложил
  • , объявляют переходный процесс свойства, и это не будет сериализировано настолько же сначала указанное моток
  • использование XStream, как указано использование boris-terzic
  • Последовательный Прокси, как указано tom-hawtin-tackline
4
ответ дан Community 7 November 2019 в 19:08
поделиться

Можно запустить путем изучения переходный процесс ключевое слово, которое отмечает поля как не часть постоянного состояния объекта.

4
ответ дан Hank 7 November 2019 в 19:08
поделиться

Полезный подход для сериализации экземпляров несериализуемых классов (или по крайней мере подклассы) известен Последовательный Прокси. По существу Вы реализуете writeReplace для возврата экземпляра совершенно другого сериализуемого класса, который реализует readResolve для возврата копии исходного объекта. Я записал пример сериализации java.awt. BasicStroke на Usenet

2
ответ дан Tom Hawtin - tackline 7 November 2019 в 19:08
поделиться

XStream является большой библиотекой для того, чтобы сделать быстрый Java к сериализации XML для любого объекта, неважно, если это является сериализуемым или нет. Даже если целевой формат XML не подходит Вам, можно использовать исходный код, чтобы изучить, как сделать это.

3
ответ дан Boris Terzic 7 November 2019 в 19:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: