Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Скачать 1.93 Mb.
|
Класс сериализации PersonВ следующем листинге показан класс Person, реализующий интерфейс Serializable. public class Person implements java.io.Serializable { private static final long serialVersionUID = 1L; private String firstName; private String lastName; private int age; private Person spouse; // супруг(а) public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getFirstName() { return firstName; } public void setFirstName(String value) { firstName = value; } public String getLastName() { return lastName; } public void setLastName(String value) { lastName = value; } public int getAge() { return age; } public void setAge(int value) { age = value; } public Person getSpouse() { return spouse; } public void setSpouse(Person value) { spouse = value; } public String toString() { return "[Person: firstName = " + firstName + " lastName = " + lastName + " age = " + age + " spouse = " + spouse.getFirstName() + "]"; } } Далее класс Person будет использоваться в примерах, чтобы показать дополнительные возможности, связанные с сериализацией Java-объектов. Модификатор поля transientИспользование при описании поля класса модификатора transient позволяет исключить указанное поле из сериализации. Это бывает полезно для секретных (пароль) или не особо важных данных. Если, например, при описании объекта Person включить следующее поле address transient public String address; то в результате сериализации и десериализации адрес объекта принимает значение по умолчанию или будет null. Модификатор transient действует только на стандартный механизм сериализации Serializable. При использовании Externalizable никто не мешает сериализовать это поле, равно как и использовать его для определения других полей. Модификатор поля staticПри стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками. Модификатор поля finalПоля с модификатором final сериализуются как и обычные. За одним исключением – их невозможно десериализовать при использовании Externalizable, поскольку final-поля должны быть инициализированы в конструкторе, а после этого в readExternal изменить значение этого поля будет невозможно. Соответственно, если необходимо сериализовать объект с final-полем неоходимо использовать только стандартную сериализацию. Пример тестирования сериализации и десериализацииДля тестирования сериализации и десериализации объекта Person будем использовать юнит-тест JUnit, в котором создадим 2 объекта, запишем объекты в файл, после чего восстановим их. Более подробно об использовании JUnit сказано на странице Тестирование программы. import static org.junit.Assert.*; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Test; import org.junit.AfterClass; import org.junit.BeforeClass; import example.Person; public class JUnitPerson { private static final String FILE = "data.ser"; private static final String FNAME_Alex = "Алексей" ; private static final String FNAME_Olga = "Ольга" ; private static final String LAST_NAME = "Иванов" ; private static final int AGE_Alex = 39 ; private static Person alex = null ; private static Person olga = null ; @BeforeClass public static void setUpBeforeClass() throws Exception { try { alex = new Person(FNAME_Alex, LAST_NAME, AGE_Alex); olga = new Person(FNAME_Olga, LAST_NAME, 38); alex.setSpouse(olga); olga.setSpouse(alex); FileOutputStream fos = new FileOutputStream(FILE); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(alex); oos.writeObject(olga); oos.close(); } catch (Exception e) { fail("Exception thrown during test: " + e.toString()); } } @AfterClass public static void tearDownAfterClass() throws Exception { // Удаление файла new File(FILE).delete(); } @Test public void testSerialization() { try { FileInputStream fis = new FileInputStream(FILE); ObjectInputStream ois = new ObjectInputStream(fis); Person alex = (Person) ois.readObject(); Person olga = (Person) ois.readObject(); ois.close(); assertEquals(alex.getFirstName(), FNAME_Alex); assertEquals(alex.getLastName() , LAST_NAME ); assertEquals(olga.getFirstName(), FNAME_Olga); assertEquals(alex.getAge() , AGE_Alex ); assertEquals(alex.getSpouse().getFirstName(), FNAME_Olga); } catch (Exception e) { fail("Exception thrown during test: " + e.toString()); } } } В примере ничего нового или удивительного не представлено – это основы сериализации, которые желательно знать, особенно при разработке WEB-приложений. |