Название функции ужасно, и код был быстро создан, но он должен работать. Обратите внимание, что это изменяет исходный объект, я не уверен, что вы хотите создать новый объект, который является расширенной версией старого.
(function(){
function parseDotNotation( str, val, obj ){
var currentObj = obj,
keys = str.split("."), i, l = keys.length - 1, key;
for( i = 0; i < l; ++i ) {
key = keys[i];
currentObj[key] = currentObj[key] || {};
currentObj = currentObj[key];
}
currentObj[keys[i]] = val;
delete obj[str];
}
Object.expand = function( obj ) {
for( var key in obj ) {
parseDotNotation( key, obj[key], obj );
}
return obj;
};
})();
var expanded = Object.expand({
'ab.cd.e' : 'foo',
'ab.cd.f' : 'bar',
'ab.g' : 'foo2'
});
JSON.stringify( expanded );
//"{"ab":{"cd":{"e":"foo","f":"bar"},"g":"foo2"}}"
Интерфейс Externalizable фактически не предоставлялся для оптимизации производительности процесса сериализации! но для предоставления средств для реализации собственной пользовательской обработки и обеспечения полного контроля над форматом и содержимым потока для объекта и его супер-типов!
Примерами этого является реализация AMF (ActionScript Message Format) удалять для передачи собственных объектов сценария действия по сети.
Существует так много различий между Serializable и Externalizable, но когда мы сравниваем разницу между пользовательскими Serializable (overrided writeObject () & amp; readObject ()) и Externalizable, тогда мы обнаруживаем, что пользовательская реализация тесно связана с классом ObjectOutputStream, где, как и в Externalizable case, мы сами обеспечиваем реализацию ObjectOutput, которая может быть классом ObjectOutputStream или может быть другим, например org.apache.mina.filter.codec.serialization.ObjectSerializationOutputStream
В случае интерфейса Externalizable
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(key);
out.writeUTF(value);
out.writeObject(emp);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.key = in.readUTF();
this.value = in.readUTF();
this.emp = (Employee) in.readObject();
}
**In case of Serializable interface**
/*
We can comment below two method and use default serialization process as well
Sequence of class attributes in read and write methods MUST BE same.
// below will not work it will not work .
// Exception = java.io.StreamCorruptedException: invalid type code: 00\
private void writeObject(java.io.ObjectOutput stream)
*/
private void writeObject(java.io.ObjectOutputStream Outstream)
throws IOException {
System.out.println("from writeObject()");
/* We can define custom validation or business rules inside read/write methods.
This way our validation methods will be automatically
called by JVM, immediately after default serialization
and deserialization process
happens.
checkTestInfo();
*/
stream.writeUTF(name);
stream.writeInt(age);
stream.writeObject(salary);
stream.writeObject(address);
}
private void readObject(java.io.ObjectInputStream Instream)
throws IOException, ClassNotFoundException {
System.out.println("from readObject()");
name = (String) stream.readUTF();
age = stream.readInt();
salary = (BigDecimal) stream.readObject();
address = (Address) stream.readObject();
// validateTestInfo();
}
Я добавил пример кода, чтобы лучше объяснить. пожалуйста, проверьте в / из объекта случай Externalizable. Они не связаны с какой-либо реализацией напрямую. Где, поскольку Outstream / Instream тесно связаны с классами. Мы можем расширять ObjectOutputStream / ObjectInputStream, но это будет немного сложно использовать.
Чтобы добавить к другим ответам, реализовав java.io.Serializable
, вы получаете возможность «автоматической» сериализации для объектов вашего класса. Нет необходимости реализовывать какую-либо другую логику, она будет работать. Java-среда выполнения использует рефлексию для определения того, как маршалировать и де-маршалировать ваши объекты.
В более ранней версии Java отражение было очень медленным, и поэтому сериализация крупных графиков объектов (например, в клиент-серверных приложениях RMI) было немного проблем с производительностью. Чтобы справиться с этой ситуацией, был предоставлен интерфейс java.io.Externalizable
, который похож на java.io.Serializable
, но с настраиваемыми механизмами для выполнения функций маршаллинга и развязывания (вам нужно реализовать методы readExternal
и writeExternal
в вашем классе). Это дает вам возможность обойти узкое место производительности отражения.
В последних версиях Java (начиная с версии 1.3, конечно) производительность отражения намного лучше, чем раньше, и поэтому это гораздо менее проблематично. Я подозреваю, что вам будет трудно получить значимую выгоду от Externalizable
с современной JVM.
Кроме того, встроенный механизм сериализации Java не является единственным, вы можете получить сторонние замены, такие как JBoss Serialization, что значительно быстрее и является заменой для замены default.
Большой недостаток Externalizable
заключается в том, что вы должны сами поддерживать эту логику - если вы добавляете, удаляете или изменяете поле в своем классе, вы должны изменить свой writeExternal
/ readExternal
методы для его учета.
Таким образом, Externalizable
является реликвией Java 1.1 дней. В этом нет необходимости.
Externalizable
помогает много i>.
– Tim Boudreau
28 August 2013 в 22:56
При рассмотрении вариантов повышения производительности не забывайте о специальной сериализации. Вы можете позволить Java делать то, что она делает хорошо или, по крайней мере, достаточно хорошо, бесплатно , и предоставлять пользовательскую поддержку для того, что она делает плохо. Обычно это намного меньше кода, чем полная поддержка Externalizable.
Сериализация предоставляет функции по умолчанию для хранения и последующего воссоздания объекта. Он использует подробный формат для определения всего графика объектов, которые нужно сохранить, например. предположим, что у вас есть связанныйList, и вы код, как показано ниже, то сериализация по умолчанию обнаружит все объекты, которые связаны и будут сериализованы. В сериализации по умолчанию объект полностью построен из его сохраненных битов без вызовов конструктора.
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("/Users/Desktop/files/temp.txt"));
oos.writeObject(linkedListHead); //writing head of linked list
oos.close();
Но если вы хотите ограничить сериализацию или не хотите, чтобы часть вашего объекта была сериализована, используйте Externalizable , Интерфейс Externalizable расширяет интерфейс Serializable и добавляет два метода: writeExternal () и readExternal (). Они автоматически вызывается при сериализации или десериализации. Во время работы с Externalizable мы должны помнить, что конструктор по умолчанию должен быть открытым, иначе код будет генерировать исключение. Пожалуйста, следуйте приведенному ниже коду:
public class MyExternalizable implements Externalizable
{
private String userName;
private String passWord;
private Integer roll;
public MyExternalizable()
{
}
public MyExternalizable(String userName, String passWord, Integer roll)
{
this.userName = userName;
this.passWord = passWord;
this.roll = roll;
}
@Override
public void writeExternal(ObjectOutput oo) throws IOException
{
oo.writeObject(userName);
oo.writeObject(roll);
}
@Override
public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException
{
userName = (String)oi.readObject();
roll = (Integer)oi.readObject();
}
public String toString()
{
StringBuilder b = new StringBuilder();
b.append("userName: ");
b.append(userName);
b.append(" passWord: ");
b.append(passWord);
b.append(" roll: ");
b.append(roll);
return b.toString();
}
public static void main(String[] args)
{
try
{
MyExternalizable m = new MyExternalizable("nikki", "student001", 20);
System.out.println(m.toString());
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Desktop/files/temp1.txt"));
oos.writeObject(m);
oos.close();
System.out.println("***********************************************************************");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Desktop/files/temp1.txt"));
MyExternalizable mm = (MyExternalizable)ois.readObject();
mm.toString();
System.out.println(mm.toString());
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}
catch(IOException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Здесь, если вы прокомментируете конструктор по умолчанию, тогда код выйдет за исключение:
java.io.InvalidClassException: javaserialization.MyExternalizable;
javaserialization.MyExternalizable; no valid constructor.
Мы можем наблюдать, что пароль является конфиденциальной информацией , поэтому я не сериализую его в методе writeExternal (ObjectOutput oo) и не устанавливаю его значение в readExternal (ObjectInput oi). Это гибкость, предоставляемая Externalizable.
Вывод вышеуказанного кода приведен ниже:
userName: nikki passWord: student001 roll: 20
***********************************************************************
userName: nikki passWord: null roll: 20
Мы можем наблюдать, поскольку мы не устанавливаем значение passWord так, чтобы оно было нулевым.
То же самое можно достичь, объявив поле пароля как переходное.
private transient String passWord;
Надеюсь, что это поможет. Прошу прощения, если я допустил ошибки. Спасибо.
Просто для полноты ключевое слово transient
также закрывает промежуток между ними.
Если вы хотите сериализовать часть своего объекта, просто установите определенные поля как transient
, отметив их как не сохраняемые, и реализуйте Serializable
.
https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
Сериализация по умолчанию несколько многословна и предполагает максимально возможный сценарий использования сериализованного объекта, и, соответственно, формат по умолчанию (Serializable) аннотирует результирующий поток с информацией о классе сериализованного объекта.
Внешняя подача дает разработчику полный поток объектов точные метаданные класса (если таковые имеются) за минимально необходимой идентификацией класса (например, его имя). Это явно желательно в определенных ситуациях, таких как закрытые среды, в которых сопоставляются производитель потока объектов и его потребителя (который подтверждает объект из потока), а дополнительные метаданные о классе не имеют никакой цели и ухудшают производительность.
Дополнительно (как указано Uri) экстернализация также обеспечивает полный контроль над кодированием данных в потоке, соответствующем типам Java. Для (надуманного) примера вы можете записать логическое значение true, как «Y», а false - «N». Вы можете сделать это вовне.
Сериализация использует определенное поведение по умолчанию для хранения и последующего воссоздания объекта. Вы можете указать, в каком порядке или как обрабатывать ссылки и сложные структуры данных, но в конечном итоге это сводится к использованию поведения по умолчанию для каждого примитивного поля данных.
Экстернализация используется в редких случаях, которые вы действительно хотите для хранения и восстановления вашего объекта совершенно по-другому и без использования механизмов сериализации по умолчанию для полей данных. Например, представьте, что у вас есть своя уникальная схема кодирования и сжатия.
Сериализация объектов использует интерфейсы Serializable и Externalizable. Объект Java является сериализуемым. если класс или любой из его суперклассов реализует либо интерфейс java.io.Serializable, либо его подчиненный интерфейс, java.io.Externalizable. Большая часть класса java является сериализуемым .
NotSerializableException
: packageName.ClassName
«Чтобы принять участие в Объект класса в процессе сериализации. Класс должен реализовывать интерфейс Serializable или Externalizable. Сериализация объекта создает поток с информацией о классах Java для сохраняемых объектов. Для сериализуемых объектов сохраняется достаточная информация для восстановления этих объектов, даже если присутствует другая (но совместимая) версия реализации класса. Интерфейс Serializable определен для идентификации классов, которые реализуют сериализуемый протокол:
package java.io;
public interface Serializable {};
InvalidClassException
«В процессе десериализации, если значение локального класса serialVersionUID отличается от соответствующего класса отправителя. то результат конфликтует как java.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
Для объектов Externalizable в контейнере сохраняется только идентификатор класса объекта; класс должен сохранять и восстанавливать содержимое. Интерфейс Externalizable определяется следующим образом:
package java.io;
public interface Externalizable extends Serializable
{
public void writeExternal(ObjectOutput out)
throws IOException;
public void readExternal(ObjectInput in)
throws IOException, java.lang.ClassNotFoundException;
}
OptionalDataException
«Поля ДОЛЖНЫ БЫТЬ В ОДНОМ ЗАКАЗЕ И ТИПЕ , как мы их написали вне. Если в потоке есть какое-то несоответствие типа, это генерирует Необязательное исключение DataDataException. @Override public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt( id );
out.writeUTF( role );
out.writeObject(address);
}
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.id = in.readInt();
this.address = (Address) in.readObject();
this.role = in.readUTF();
}
ObjectOutput
, сериализуются. Пример «Реализует Serializable
class Role {
String role;
}
class User extends Role implements Serializable {
private static final long serialVersionUID = 5081877L;
Integer id;
Address address;
public User() {
System.out.println("Default Constructor get executed.");
}
public User( String role ) {
this.role = role;
System.out.println("Parametarised Constructor.");
}
}
class Address implements Serializable {
private static final long serialVersionUID = 5081877L;
String country;
}
Пример « реализует Externalizable
class User extends Role implements Externalizable {
Integer id;
Address address;
// mandatory public no-arg constructor
public User() {
System.out.println("Default Constructor get executed.");
}
public User( String role ) {
this.role = role;
System.out.println("Parametarised Constructor.");
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt( id );
out.writeUTF( role );
out.writeObject(address);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.id = in.readInt();
this.address = (Address) in.readObject();
this.role = in.readUTF();
}
}
Пример
public class CustomClass_Serialization {
static String serFilename = "D:/serializable_CustomClass.ser";
public static void main(String[] args) throws IOException {
Address add = new Address();
add.country = "IND";
User obj = new User("SE");
obj.id = 7;
obj.address = add;
// Serialization
objects_serialize(obj, serFilename);
objects_deserialize(obj, serFilename);
// Externalization
objects_WriteRead_External(obj, serFilename);
}
public static void objects_serialize( User obj, String serFilename ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
// java.io.NotSerializableException: com.github.objects.Address
objectOut.writeObject( obj );
objectOut.flush();
objectOut.close();
fos.close();
System.out.println("Data Stored in to a file");
}
public static void objects_deserialize( User obj, String serFilename ) throws IOException{
try {
FileInputStream fis = new FileInputStream( new File( serFilename ) );
ObjectInputStream ois = new ObjectInputStream( fis );
Object readObject;
readObject = ois.readObject();
String calssName = readObject.getClass().getName();
System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException
User user = (User) readObject;
System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);
Address add = (Address) user.address;
System.out.println("Inner Obj : "+ add.country );
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void objects_WriteRead_External( User obj, String serFilename ) throws IOException {
FileOutputStream fos = new FileOutputStream(new File( serFilename ));
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
obj.writeExternal( objectOut );
objectOut.flush();
fos.close();
System.out.println("Data Stored in to a file");
try {
// create a new instance and read the assign the contents from stream.
User user = new User();
FileInputStream fis = new FileInputStream(new File( serFilename ));
ObjectInputStream ois = new ObjectInputStream( fis );
user.readExternal(ois);
System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);
Address add = (Address) user.address;
System.out.println("Inner Obj : "+ add.country );
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@see