2015-08-25 3 views
1

Я изучаю эффективную java и в неизменности (пункт 15) написано, что: Сделайте защитные копии (пункт 39) в конструкторах, аксессуарах и readObject методов (позиция 76).Почему строка в java не переопределяет readObject?

И в пункте 76 Рекомендуется переопределить readObject и создать защитную копию изменяемого объекта путем компрометации окончательного ключевого слова. Поэтому я проверил класс String в java и проверил, сделали ли они то же самое для final char value[];, но readObject не переопределяется.

Я смущен об этом? Пожалуйста, ответьте.

+0

Одно замечание: 'String' просто оберткой' char' массив. Это не похоже на пример в пункте 76, где происходит специальная проверка экземпляров 'Date' (т. Е. В примере« конец »должен быть больше, чем« start »). – Powerlord

+0

Спасибо за ответ, но char [] также является изменчивым государством? –

ответ

2

Строки, массивы и перечисления являются частными случаями в сериализации и не сериализуются через readObject/writeObject, как и другие объекты.

Вот комментарий от String.java:

/** 
    * Class String is special cased within the Serialization Stream Protocol. 
    * 
    * A String instance is written initially into an ObjectOutputStream in the 
    * following format: 
    * <pre> 
    *  <code>TC_STRING</code> (utf String) 
    * </pre> 
    * The String is written by method <code>DataOutput.writeUTF</code>. 
    * A new handle is generated to refer to all future references to the 
    * string instance within the stream. 
    */ 

и здесь особые случаи из ObjectOutputStream.java:

// remaining cases 
if (obj instanceof String) { 
    writeString((String) obj, unshared); 
} else if (cl.isArray()) { 
    writeArray(obj, desc, unshared); 
} else if (obj instanceof Enum) { 
    writeEnum((Enum) obj, desc, unshared); 
} else if (obj instanceof Serializable) { 
    writeOrdinaryObject(obj, desc, unshared); 
} else { 
    if (extendedDebugInfo) { 
     throw new NotSerializableException(
      cl.getName() + "\n" + debugInfoStack.toString()); 
    } else { 
     throw new NotSerializableException(cl.getName()); 
    } 
} 
2

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

Что касается защитной копии, поскольку строки неизменны - вы не должны беспокоиться об этом.

+1

Пункт 76 OP ссылается на то, что пишет readObject защитно, чтобы вы, например, не может создать String, чья начальная 'int offset' находится вне своего значения' char []. Строка вместо этого защищает от этого, будучи особым случаем в сериализации. –

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