• ,

level20.lesson04.task03


/* Как сериализовать Singleton?
Два десериализованных объекта singleton и singleton1 имеют разные ссылки в памяти, а должны иметь одинаковые.
В класс Singleton добавьте один метод (погуглите), чтобы после десериализации ссылки на объекты были равны.
Метод main не участвует в тестировании.
*/


Можно не гуглить в переводах есть статья на эту тему.

20 комментариев

Baggio
В класс Singleton добавил метод
protected Object readResolve() {
			return getInstance();
		}


Вывод такой:

Instance reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@17a29a1
Instance reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@17a29a1
=========================================================
Object reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@17a29a1
Object reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@17a29a1

Проверку на сервере не проходит.
Kverde
Насколько помню, у меня был такой же метод, возможно, поможет сужение типа или изменение модификатора доступа.
Baggio
  • Baggio
  • 0
  • Комментарий отредактирован 2014-07-04 17:03:37 пользователем Baggio
Игра с модификаторами доступа не помогла.
Сужение типа до Singleton изменило вывод. Теперь поля ссылаются на разные объекты.

Решено. В Singleton нужно было добавить:
private static final long serialVersionUID = 1L;
DarkCloud
А у меня приняло с такой вот функцией, больше ниче не добавлял

Object readResolve ()
        {
            return getInstance();
        }
Nestrik
возвращал сразу переменную ourInstance, по заданию нагуглил это
Lynx89
Отличная ссылка, Nestrik . Очень помогло☺
valera7979
походу задача взята с этого ресурса)))
AlexSav7
сто процентов)
один в один
MindIbniM
что-то непонятно совсем, что этот метод делает?
Captain
Instance reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@197a37c
Instance reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@197a37c
=========================================================
Object reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@197a37c
Object reference check: com.javarush.test.level20.lesson04.task03.Solution$Singleton@197a37c

Вот такой вывод получаю в консоль, добавил метод getResolve (){}, добавил serialVersionUID — задачу не принимает, подскажите в чем пможет быть проблема?
Baco
Вот хорошая статья про Singleton, сразу все становиться ясно.
Your text to link...
Nikita686
Непонятно, что делает данный метод:
Object readResolve ()
{
return getInstance();
}
aleratorio
  • aleratorio
  • 0
  • Комментарий отредактирован 2015-07-10 16:59:03 пользователем aleratorio
Этот метод возвращает объект, который в итоге возвращает метод readObject() при десериализации. Для Singleton-a мы должны вернуть instance, который у нас в единственном экземпляре. Если мы не определим этот метод, то наш десериализованный Singleton будет новым объектом.

Вот вам для примера, как работает readResolve:
import java.io.*;

public class Solution implements Serializable
{
	private String str = "aaa";

	public String toString() { return str; }

	public static void main(String[] args) throws IOException, ClassNotFoundException
	{
		PipedOutputStream pos = new PipedOutputStream();
		PipedInputStream pis = new PipedInputStream(pos);
		ObjectOutputStream out = new ObjectOutputStream(pos);
		ObjectInputStream in = new ObjectInputStream(pis);

		Solution s = new Solution();

		out.writeObject(s);
		out.flush();

		Object o = in.readObject(); // <- Тут получается объект, возвращённый readResolve

		if(o instanceof Solution)
		{
			System.out.println("Solution:" + o);
		}
		else if(o instanceof Integer)
		{
			System.out.println("Integer:" + o);
		}
		else
		{
			System.out.println("?????");
		}

		in.close();
		out.close();
	}

	private Object readResolve() throws ObjectStreamException
	{
		return Integer.valueOf(1293);  // <- Подменяем объект на Integer вместо Solution
	}
}
запустите так, а потом закомментируйте readResolve и увидите разницу
tarrus
Задачу решил до конца не понимая ее. Прошу объясните пожалуйста на пальцах почему и как помогает метод readResolve()?
Patrio
Удалось понять, что после readObject() перед отдачей объекта, вызывается метод readResolve(). Поэтому мы в этот метод вкидываем наш getInstance(), тогда инициализируется и возвращается 1 и тот же объект при любом readObject(). Иначе каждый раз будет создаваться новый Синглетон
stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve
Valocop
Интересно, получается мы переопределяем метод readResolve(), тогда он по умолчанию выбрасывает new Singltin? А что на счет других классов, если мы создали объект, записали его (writeObject()) и потом при чтении (readObject()) получаем ссылку на другой объект, но с теми же параметрами(переменные имя и т.д.)? Почему так сделали? Может ли кто объяснить, ведь наверняка этому есть объяснение? буду очень благодарен)
sergentum
я так понимаю что это как бы не решение проблемы, а типа костыль для того чтобы этот класс подерживал сериализацию. просто на самом деле получается мы игнорируем то что было сериализовано и подменяем объект.
kiberMouse
если я все правильно понял, то ровно наоборот — мы игнорируем ссылку на новый объект, подменяя ее сылкой на сериализуемый. Хотя, я не понял как это происходит.
Если не прав — поправьте.
zinykov
интересно про Singlton Видео с youtube
Rim
  • Rim
  • 0
Читаем статью про Singleton
Там в самом конце статьи написан метод для решения задачи.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.