Вместо того, чтобы использовать метод, в котором вы назначаете адрес электронной почты для пользователя, может быть лучшим вариантом для поиска адреса электронной почты в вашей базе данных.
Примером может быть:
Когда вы реализуете интерфейс java.io.Serializable для создания сериализуемого класса, компилятор ищет статическое конечное поле с именем «serialVersionUID» типа long. Если класс не указал это поле явно, то компилятор создаст одно такое поле и присвоит ему значение, которое выходит из зависимого от реализации вычисления serialVersionUID. Это вычисление зависит от различных аспектов класса, и оно следует за спецификациями сериализации объектов, данными Sun. Но значение не гарантируется во всех реализациях компилятора.
Это значение используется для проверки совместимости классов в отношении сериализации, и это выполняется при де-сериализации сохраненного объекта. Последовательность выполнения Serialization проверяет, что serialVersionUID класса отправителя (который использовался для сохранения состояния объекта в потоке) и класса получателя (класс, который используется для восстановления объекта, возможно, в какой-либо другой системе) оба они точно такие же. Если система приемника загрузила класс с некоторым другим идентификатором serialVersionUID, чем класс, используемый в процессе сериализации, мы получаем InvalidClassException.
ПРИМЕЧАНИЕ. Настоятельно рекомендуется явно объявить и инициализировать статический окончательный поле типа long и имя 'serialVersionUID' во всех ваших классах, которые вы хотите сделать Serializable, вместо того, чтобы полагаться на вычисление значения по умолчанию для этого поля по умолчанию. Это вычисление чрезвычайно чувствительно и может варьироваться от одной реализации компилятора к другой, и, следовательно, вы можете получить InvalidClassException даже для одного и того же класса только потому, что вы использовали различные реализации компилятора на отправителе и на концах приемника процесса сериализации.
В большинстве случаев вы использовали бы «частный» спецификатор доступа только для этого поля, поскольку объявление обычно применяется только к классу, объявляющему его, и нам действительно не нужно либо наследовать это поле в подклассах OR, либо доступ к нему извне. Итак, вряд ли есть какая-то причина, почему мы не должны держать ее «частной».
Если кто-то снова столкнется с этой проблемой по отношению к EJB TimerTask - как я и сделал - вот подсказка, если вы используете WebSphere Application Server:
Есть 2 командных файла / сценарии оболочки в папке bin файла, которая может отображать и удалять задачи таймера EJB. В моем случае у меня были некоторые задачи таймера, которые сериализовали объекты с другим устаревшим serialVersionUID. Я не мог избавиться от них, поскольку сериализованные объекты действительно изменились. Поэтому я просто использовал те:
findEJBTimers.bat cancelEJBTimers.bat
Ваши задачи таймера исчезли, а также сообщения об ошибках. В моем случае это было именно то, что мне было нужно, но было сложно получить эту информацию.
Хорошо, так как я попрошу привести пример и мою часть:
Вот список и метрики производительности для различных форм сериализации PoJos
Вам придется судить о компромиссах с производительностью и удобством. Но, поскольку я сказал «JSON» как средство сериализации, вот здесь тривиальный пример, который не зависит от компилятора. В принципе, если вы не изменили структуру своего pojo на принимающей стороне, это совершенно не имеет значения, когда / how / где вы ее скомпилируете (на самом деле, это даже не должно быть между двумя JVM). Как вы можете видеть из ссылки, JSON на самом деле является одним из самых медленных, а XML - просто свинья. Но оба они имеют решающее преимущество в поддержке повсеместно. XML даже позволяет применять таблицы стилей.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
Код
@Test
public void testJSON() throws Exception {
Foo expected = new Foo(1,"Christian",1000000.00d);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String testJson = gson.toJson(expected);
System.out.println(testJson);
Foo result = gson.fromJson(testJson, Foo.class);
assertEquals(expected,result);
}
public static class Foo {
private String name;
private Integer age;
private Double paycheck;
public Foo(Integer age, String name, Double paycheck) {
this.age = age;
this.name = name;
this.paycheck = paycheck;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo foo = (Foo) o;
if (age != null ? !age.equals(foo.age) : foo.age != null) return false;
if (name != null ? !name.equals(foo.name) : foo.name != null) return false;
if (paycheck != null ? !paycheck.equals(foo.paycheck) : foo.paycheck != null) return false;
return true;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (paycheck != null ? paycheck.hashCode() : 0);
return result;
}
}
Выход
{
"name": "Christian",
"age": 1,
"paycheck": 1000000.0
}
Вы получаете это исключение, когда пытаетесь десериализовать объект, который был сериализован с несовместимой (обычно более ранней) версией того же класса.
Если вы явно не указали serialVersionUID
в своем класса Serializable
, то значение будет генерироваться на основе полей (не transient
) вашего класса. Это делается для того, чтобы не восстанавливать частичные объекты (лучше провалиться, чем слепо продолжить с возможно сломанным объектом).
В системах веб-приложений для сеанса используется обычное использование сериализации : если вы поместите значение в сеанс, вероятно, он будет сериализован в конце концов (для поддержки кластеризации или просто для получения постоянных сеансов).
Итак, либо сохраняют все ваши классы совместимые между версиями или , гарантируют, что не восстановить их не нарушит ваше приложение (т. е. не храните важную информацию таким образом).