Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Создание собственных исключений


Автор: simanyay 30.6.2005, 13:26
Код

package org.simanyay.jizer.kernel;

public class CompilerException extends Exception {
    private static final long serialVersionUID = 42L; // Зачем вот это нужно?
    
    public CompilerException() {
    }
    
    public CompilerException(String msg) {
        super(msg);
    }

    // bla-bla
}


Если я это поле убираю, то появляется следующий warning:
Цитата
The serializable class CompilerException does not declare a static final serialVersionUID field of type
long


Так зачем нужно это поле? Если мне не изменяет память, я раньше прекрасно обходился без него. У Эккеля не нашёл. В доках к JDK - не понял smile

Eclipse 3.1M7
JDK Compliance: 5.0

Заранее спасибо.

Автор: Andyb 30.6.2005, 14:01
как я понимаю serialVersionUID это описание версии данного класса и является необязательным,
а warning'и генерирует Eclipse, в NetBeаns'е все компилиться без warning'ов в JBuilder'е тоже,
а вот JCreator тоже плюется

Автор: simanyay 30.6.2005, 14:15
Спасибо.

Автор: Domestic Cat 1.7.2005, 10:08
serialVersionUID - это версия класса. При десериализации JVM проверяет версию класса десериализуемого объекта и сравнивает с версией загруженного класса, если они не совпадают, бросается иксепшн.
Если значения этого поля одинаковы, то считается что версии классов совместимы. Предположим , версия приложения 1.0 сериализует класс А, а в версии 2.0 этот класс изменен (добавили поле), то сама по себе JVM отказалась бы загрузить старые объекты класса А, поскольку на самом деле это разные классы. Но достаточно указать в А поле serialVersionUID, и не менять его в последующей версии, чтобы таким образом заставить JVM считать, что это объекты одного и того же класса.

Автор: simanyay 1.7.2005, 10:23
Понятно, спасибо.

Автор: carper 5.7.2005, 16:29
Domestic Cat
Что касается serialVersionUID все верно, но только, насколько я помню, эта переменная не только НЕ ОБЯЗАТЕЛЬНА, но, в общем случае, НЕ ЖЕЛАТЕЛЬНА с точки зрения гибкости и устранения возможных ошибок при изменении класса.
А сам серийный номер генерится автоматически при каждом создании экземпляра (=> обычно статически задают номер только для классов, которые мы гарантированно не будем менять, с целью избегнуть затрат на автоматическую генерацию, ну, и еще несколько более экзотических вариантов можно придумать).

Поэтому совершенно неясно почему это ругается компилятор ?

Если посмотрим на стандартные классы SUN, расширяющие Exception, то и там находим, что serialVersionUID задается явно.

Я, честно говоря, не совсем понимаю причину – разве, что исключения рассматриваются как потенциально неизменные объекты, находящие большое применение при сериализации + кажется сам механизм генерации SUID может отличаться для различных вариантов JVM, соотвественно компилятор от IBM на это и намекает.
По крайней мере, IDEA в вышеприведенном примере не генерит никаких ошибок или предупреждений.



P.S. Кстати, для генерации своего SUID разумно использовать serialver.exe все же от SUN – будет больше совместимости при разработке на разных IDE.


Автор: simanyay 5.7.2005, 16:59
Цитата(carper @ 5.7.2005, 18:29)

Что касается serialVersionUID все верно, но только, насколько я помню, эта переменная не только НЕ ОБЯЗАТЕЛЬНА, но, в общем случае, НЕ ЖЕЛАТЕЛЬНА с точки зрения гибкости и устранения возможных ошибок при изменении класса.


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

Автор: carper 5.7.2005, 17:44
simanyay
" не думаю, что разработчики Eclipse принуждали бы использовать нежелательные переменные. "

А они здесь не совсем "нежеланные", я не уверен в том, что правильно нашел причину этого явления, но полагаю, что виртуальная машина от IBM может использовать иную методику рассчета SUID, соот-но и приходится заботиться от совместимости со стандартной машиной от SUN.

Хотя меня гложут смутные подозрения, что я горожу какую-то ересь. smile
По крайней мере, методика подсчета от SUN весьма прозрачна и логична.

Может здесь дело в том, что "хорошим тоном" для исключений де-факто приняли использовать статический номер, после чего Eclipse решил это правило довести "до уровня генерации предупреждения" smile

Автор: simanyay 5.7.2005, 18:05
Цитата(carper @ 5.7.2005, 19:44)

Может здесь дело в том, что "хорошим тоном" для исключений де-факто приняли использовать статический номер, после чего Eclipse решил это правило довести "до уровня генерации предупреждения" smile


Вот этот вариант мне больше всех импонирует smile

Автор: Domestic Cat 5.7.2005, 22:34
Цитата(carper @ 5.7.2005, 07:29)
НЕ ЖЕЛАТЕЛЬНА с точки зрения гибкости и устранения возможных ошибок при изменении класса.

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

Автор: carper 6.7.2005, 09:29
Domestic Cat
"Он используется тогда когда нужно обеспечить совместимость с предыдущими версиями, как он может повлиять на устранение ошибок? "

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

Да и вообще, более логичным выглядело бы задание номера на классе реализущим не Serializable а Externalizable, по крайней мере, он жестче определяет поведение программиста в части самостоятельного использования readExternal и writeExternal (будете ли вы переопределять readObject и writeObject еще бабушка надвое сказала) , т.е. сложней будет забыть изменить номер.


И все же меня заинтриговало решение самой SUN о явном задании номера классов- исключений.
После отпуска попробую покопать, если чего найду с удовольствием сообщу.





Автор: inxaoc 27.10.2006, 14:46
Подскажите пожалуйста как генерить этот ID в Intellij Idea

Автор: Shurr 27.10.2006, 17:51
Цитата(inxaoc @ 27.10.2006,  14:46)
Подскажите пожалуйста как генерить этот ID в Intellij Idea

Есть специальный плагин http://www.intellij.org/twiki/bin/view/Main/SerialVersionUIDPlugin. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)