Прочитал уже все рекомендованные статьи, полистал инфо.джавараш по этой задаче, уже даже жмякнул валидацию, чтобы посмотреть, после каких пунктов задача засчитывается. И все равно ничего толком не понял. Намешал сериализацию с внутренними классами и получил в голове полный бардак. Объясните, пожалуйста, по шагам, что происходит в этой задаче и почему надо делать именно так.

Найти ошибки

Почему-то при сериализации/десериализации объекта класса B возникают ошибки.

Найди проблему и исправь ее.

Класс A не должен реализовывать интерфейсы Serializable и Externalizable.

В сигнатуре класса В ошибки нет :).

Метод main не участвует в тестировании.

public class Solution {
    public static class A {
        protected String name = "A";

        public A(String name) {
            this.name += name;
        }

    }

    public class B extends A implements Serializable {
        public B(String name) {
            super(name);
            this.name += name;
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(arrayOutputStream);

        Solution solution = new Solution();
        B b = solution.new B("B2");
        System.out.println(b.name);

        oos.writeObject(b);

        ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(arrayOutputStream.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(arrayInputStream);

        B b1 = (B)ois.readObject();
        System.out.println(b1.name);
    }
}

По прочитанным материалам понял, что нужен пустой конструктор в классе А, понял, что он вызывается при десериализации, но не понял, почему. Это просто условие, которое надо соблюдать без понимания? Any ideas?

Также нужно имплементировать Serializable в класс Soulution, правильно? Это о внутренних классах. Пока не будем их ворошить.

Дальше байт-массив, обджект-аутпут-стрим и пишем в него созданный объект B. Что тут происходит? Записываем поля объекта? Т.е. только name? Ибо больше ничего нету. Что еще записывается? Какие-то данные про родителя? Данные про внешние/внутренние классы?

Дальше. Валидатор говорит, что в классе B надо создавать методы writeObject/readObject и дальше вызывать дефолтные. Это мне вообще взорвало мозг. А что тогда вот это - oos.writeObject(b)? Это не дефолтный метод класса OOS? И даже если я напишу то, что предлагает валидатор, как оно вообще будет работать?

Объясните, плиз, на пальцах. А то эта простая(по комментариям на форуме) тема меня скоро убьет :)

задан 20 Мар, 09:56

Morfin's gravatar image

Morfin
1776
одобрено: 25%


Задачу решил. Более-менее въехал. Но вот этот момент все еще остается непонятным. Объясните хоть его, пожалуйста.

 private void writeObject(ObjectOutputStream oos) throws IOException {
      oos.defaultWriteObject();
      oos.writeObject(name);
      }

 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
      ois.defaultReadObject();
      name = (String) ois.readObject();
      }

Зачем вызывается метод defaultWriteObject()?

Из джавадока: Write the non-static and non-transient fields of the current class to this stream. This may only be called from the writeObject method of the class being serialized. It will throw the NotActiveException if it is called otherwise.

Т.е. мы два раза записываем одно поле name? Один раз через дефолт, второй - вручную? Зачем?

ссылка

опубликован 20 Мар, 15:30

Morfin's gravatar image

Morfin
1776
одобрено: 25%

Спасибо, получилось! :)

(20 Мар, 18:18) EleNikIvi
(20 Мар, 18:10) Morfin

Про редактирование ссылки не совсем понятно... Как заменить ссылку на слово?

(20 Мар, 18:08) EleNikIvi

Мейкс сенс. Так и думал :)

(20 Мар, 18:01) Morfin
1

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

(20 Мар, 17:57) EleNikIvi

з.ы. редактировать ссылку можно вот так: [тут любой текст, например "цытата"] и ("и тут ссылка. между скобками "и" не надо")

(20 Мар, 17:37) Morfin

Но переменных класса B у нас нет(как я понимаю, процесс сериализации не учитывает наследуемую переменную)

(20 Мар, 17:29) Morfin
1

Цитата:

Теоретически можно в классе B определить методы, о которых я говорил в начале – readObject и writeObject, – в начале которых производить (де-)сериализацию переменных класса B через in.defaultReadObject/out.defaultWriteObject, а потом – (де-)сериализацию доступных переменных из класса A

(20 Мар, 17:25) EleNikIvi
Ваш ответ
включить просмотр

Следить за вопросом

По Email:

После авторизации вы сможете подписаться на любые обновления здесь

Основы Markdown

  • *italic* or _italic_
  • **bold** or __bold__
  • ссылка:[текст](http://url.com/ "заголовок")
  • изображение?![alt текст](/path/img.jpg "заголовок")
  • нумерованный список: 1. Foo 2. Bar
  • Для того чтобы добавить разрыв строки просто добавьте два пробела.
  • основные HTML тэги, также поддерживаются

Тэги:

×176
×24

Задан: 20 Мар, 09:56

Просмотров: 92 раз

Отредактирован: 20 Мар, 18:18