2013-06-28 2 views
0

я следующий код:Сериализация объектов (Java)

import java.io.*; 

public class TestSer { 
    public static void main(String[] args) { 
     SpecialSerial s = new SpecialSerial(); 
     try { 
      ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("myFile")); 
      os.writeObject(s); os.close(); 
      System.out.print(++s.z + " ");       ...(1) 
      ObjectInputStream is = new ObjectInputStream(new FileInputStream("myFile")); 
      SpecialSerial s2 = (SpecialSerial)is.readObject(); 
      is.close(); 
      System.out.println(s2.y + " " + s2.z); 
     } catch (Exception x) { 
      System.out.println("exc"); 
     } 
    } 
} 

class SpecialSerial implements Serializable { 
    transient int y = 7; 
    static int z = 9; 
} 

Теперь, когда я побежал код, выход был "10 0 10". Но почему это «10 0 10», а не «10 0 0»? Я имею в виду, когда я десериализовал объект, y и z (будучи временными и static resp) должны были возвращаться как 7 и 9, которые являются значениями по умолчанию (пожалуйста, исправьте меня в этот момент, потому что я думаю, что значения, которые получает объект после десериализации являются значениями по умолчанию). И что означает синтаксис «++ object.var» (см. (1)). Это то же самое, что «Object var ++», то есть «++ s.z», то же самое, что и «s.z ++»?

ответ

2

Там только одна ячейка памяти, которая хранит значение SpecialSerial.z в памяти с момента z объявлен static. Это значение имеет приоритет над значением, десериализованным из файла.

Добавление:

private void writeObject(ObjectOutputStream oos) throws IOException { 

    oos.defaultWriteObject(); 
    oos.writeInt(z); 
    System.out.println("session serialized"); 
} 

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 

    ois.defaultReadObject(); 
    z = ois.readInt(); 
} 

делает перезаписывает статическое значение z с одним десериализованными из файла.

Я бы не предложил эту технику, так как это может вызвать проблемы, которые трудно решить.

+0

+1, но для статики нет «десериализованного значения из файла», поэтому ничего не должно «иметь приоритет над». – EJP

0

Имейте в виду, что статические переменные находятся на уровне класса.

Сериализация объектов осуществляется на уровне объекта. Поэтому сериализация и десериализация не влияют на счет статической переменной.

Поскольку y является временным, оно будет установлено на значение по умолчанию, которое равно 0 после считывания объекта.

0
System.out.print(++s.z + " "); 

Выход 10, потому что ваш объект находится в памяти, сериализация не стирает временные поля, это просто игнорировать их на сериализации.

System.out.println(s2.y + " " + s2.z); 

Выход 0 и 10, 0, потому что у преходяще поле, это не сохраняется на боб сериализации, поэтому при десериализации она получает значение по умолчанию, ведьма 0 для междунар.

10 - это потому, что z - статическое поле, то есть оно не связано с экземпляром, сериализация также не стирает его.

Оно равно:

s2.z and SpecialSerial.z 
0
System.out.print(++s.z + " "); 

Это увеличит z на единицу, а затем распечатает его.

И поскольку z статично, оно будет одинаковым для всех экземпляров, и поэтому после десериализации будет также 10. Это больше не 9, потому что вы увеличили стоимость до сериализации.

y равно 0, поскольку его объявленный переходный процесс означает, что он не будет частью сериализованного объекта. Поэтому при выполнении десериализации значения не будут установлены.

1

Теперь, когда я запускал код, выход был «10 0 10». Но почему это «10 0 10», а не «10 0 0»?

Когда объект получен путем десериализации, переходные переменные заполняются значениями по умолчанию. Но он имеет те же static variable (или переменную класса), которые существуют в JVM для данного класса. Вот почему значение s.z отображается как 10, которое является существующим значением z в текущем приложении.

"++ s.z" такой же, как "s.z ++"?

++s.z использует прединкремент оператор, что означает увеличить значение s.z первых, а затем распечатать его. Принимая во внимание, что s.z++ использует оператор postincrement, что означает сначала напечатать значение s.z, а затем увеличить.

1

++ sz означает «добавить 1 в sz, а затем использовать», s.z ++ означает «использовать sz, а затем добавить 1» ..., чтобы ответить на ваш основной вопрос, ответьте на этот простой вопрос: в своем классе «Специальная серия» вы переопределяете метод «isClose()»? Можете ли вы поместить код?

1

Статические переменные связаны с классом. Таким образом, как только вы увеличиваете z от 9 до 10, он останется 10 до тех пор, пока программа будет запущена. Кроме того, переходная переменная y не получает никакого значения, назначенного во время десериализации, и, следовательно, ее значение равно 0 (значение по умолчанию для переменной int).