2013-02-12 2 views
2

У меня есть квадратное дерево *, которое я хотел бы использовать на нескольких разных машинах. Вызов конструктора (т.е. построения дерева) занимает много времени. Я не хочу строить дерево каждый раз, когда мне нужно его использовать.Java: Можно ли десериализовать объект без вызова его конструктора?

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

Может ли сериализация помочь мне с этим? Я знаю, что я могу сериализовать дерево, сохранить его на диск, а затем десериализовать (это все, что я знаю о сериализации). Насколько мне известно, на этапе десерилизации требуется конструктор по умолчанию для построения дерева. Поскольку построение дерева является дорогостоящим, это бесполезно для меня.

Есть ли способ импортировать сохраненное дерево без необходимости его переустанавливать каждый раз?

* базовый код четырехъядерный дерево, которое я использовал: https://bitbucket.org/utcompling/textgrounder/src/f38150c7f33a/src/main/java/ags/utils/KdTree.java

Извинения, если это слишком основной, она тесно связана с: https://stackoverflow.com/questions/14701245/how-do-i-perform-kd-tree-lookups-in-hadoop

редактировать: Итак, похоже, что без аргументов конструктора наименее унаследованный класс - тот, который будет вызываться. Вот мой hirearchy:

аннотация KDTree

квадрадерево расширяет KdTree

SpecialQuadTree (имеет экземпляр квадрадерево)

Теперь, я только в состоянии сериализовать SpecialQuadTree, когда я делаю все Сериализуемый (в противном случае я 'получение NotSerizable или InvalidClassException без действительного конструктора):

аннотация KDTree реализует Serializable

квадрадерево расширяет KdTree реализует Serializable

SpecialQuadTree реализует Serializable (имеет экземпляр квадрадерева)

Таким образом, я полагаю, я могу взять Сериализуемые от KdTree и затем дать ему делать-ничего не-арг конструктора? Это непросто, я не писал и не понимаю класс KdTree. Я полагаю, я мог бы подкласс, не дают подклассы ничегонеделания нет-арг конструктор, и наследуют квадрадерево от этого ...

редактировать: ИТАК, у меня есть абстрактный класс абстрактный KDTree реализует Serializable

и от этого я расширяю: квадрадерево расширяет KdTree реализует Serializable

из всех моих экспериментов, мне нужно реализовать Сериализуемый на обоих. Теперь

public QuadTree() { 
    super(2, 1000000); 
    System.out.println("QuadTree no-args!"); 
} 

и

protected KdTree(int dimensions, Integer sizeLimit) { 
    System.out.println("KdTree, constructor!"); 

Поскольку я никогда не видел его распечатать (в сторону от первоначального строительства ...), я думаю, это все хорошо.

+0

Вы предполагаете, что сериализация и десериализация будут эффективнее, чем использование стандартизованного метода сериализации, такого как XML/JSON? – amphibient

+0

В прошлом я всегда использовал JSON для сохранения объектов. Проблема, которую я имею сейчас, заключается в том, что я понятия не имею, как написать метод, который преобразует мой объект в JSON. – dranxo

+0

Предлагаю посмотреть на Google protocol buf –

ответ

2

Насколько мне известно, шаг deserilization необходим конструктор по умолчанию построение дерева

Нет, если вы принимаете о сериализации объектов Java это не так.

похоже, что конструктор no-arg наименее унаследованного класса является тем, который будет вызываться.

No. The No-арг конструктор ближайшего не сериализуемого базового класса называется.

Я полагаю, что могу взять Serializable с KdTree, а затем дать ему конструктор no-args do-nothing?

Почему? Просто оставьте это в покое.

+0

ОК. Я новичок в этом, действительно ли это «реализует Serializable» на всех моих классах, а затем Java показывает это? – dranxo

+2

Будет вызываться конструктор по умолчанию для самого производного класса, отличного от 'Serializable' (разные правила для' Externalizable', но это нечетно). –

+0

Обратите внимание, что «конструктор по умолчанию» - это конструктор * no-args *, который Java создает для вас, если ваш класс не определяет конструкторы. Поэтому мы, вероятно, говорим * no-args * constructors, а не конструкторы по умолчанию. –

3

Когда объект десериализован в Java, вызываются только некоторые из конструкторов no-args (см. this post).

Самый простой способ - сделать все вовлеченные классы Serializable. Тогда никто из ваших конструкторов не будет вызван. Если вы не можете этого сделать, убедитесь, что ваши классы Serializablehave access to the no-args constructor of the first non-Serializable class.

В случае не- Serializable базового класса, который находится под вашим контролем, вы можете переместить дорогую логику к другому конструктору (скажем, с фиктивным boolean аргумента) и обеспечивают простой не-арг конструктор, который ничего не делает , Тогда все ваши поля будут там после десериализации без затрат на вычисления.

Конечным источником информации является the serialization spec.

+0

Хорошее предложение. Сейчас я попробую попробовать. – dranxo

0

Если вы используете Джексон, как насчет того, чтобы создать собственный десериализатор и подключиться к классу, где вы пытаетесь десериализовать?

Смежные вопросы