Transitioning Serialization and Deserialization Processes to
matlab.mixin.CustomElementSerialization
The recommended process for customizing serialization and
deserialization of objects is to use the matlab.mixin.CustomElementSerialization
mixin (since R2024b). Transitioning to the
mixin from an existing implementation of loadobj
and
saveobj
can give you greater control of the serialization process in
future revisions of the class. However, some existing implementations might make
loadobj
and saveobj
the better option.
Preserve Version Compatibility Between loadobj
and saveobj
Implementations and
matlab.mixin.CustomElementSerialization
The first version of the Rectangle
class represents a rectangle using
the coordinates of the lower-left and upper-right vertices. The saveobj
and loadobj
methods only handle the property data using structures.
This implementation enables flexibility for any future class versions that use different
properties to define the
rectangle.
classdef Rectangle % Version 1 properties x1 y1 x2 y2 end methods function obj = Rectangle(x1,y1,x2,y2) obj.x1 = x1; obj.y1 = y1; obj.x2 = x2; obj.y2 = y2; end function s = saveobj(obj) s.x1 = obj.x1; s.y1 = obj.y1; s.x2 = obj.x2; s.y2 = obj.y2; end end methods(Static) function obj = loadobj(s) obj = Rectangle(s.x1,s.y1,s.x2,s.y2); end end end
Version 2 of the class represents the rectangle using the coordinates of the
lower-left vertex, the height, and the width. The revision maintains compatibility by
implementing saveobj
and loadobj
methods to ensure
that Version 2 of the class can load instances saved under Version 1, and Version 1 of
the class can load instances saved under Version 2. The constructor accepts the same
property values of Version 1, namely the coordinates of the lower-left and upper-right
coordinates. The loadobj
method calls the Rectangle
constructor with those values. To preserve compatibility with Version 1, the
saveobj
method converts the new properties back to the old
properties and saves them as a structure.
classdef Rectangle % Version 2 properties x0 y0 width height end methods function obj = Rectangle(x1,y1,x2,y2) obj.x0 = x1; obj.y0 = y1; obj.width = x2 - x1; obj.height = y2 - y1; end function s = saveobj(obj) s.x1 = obj.x0; s.y1 = obj.y0; s.x2 = obj.x0 + obj.width; s.y2 = obj.y0 + obj.height; end end methods(Static) function obj = loadobj(s) obj = Rectangle(s.x1,s.y1,s.x2,s.y2); end end end
Version 2a of the Rectangle
class is a subclass of
matlab.mixin.CustomElementSerialization
, but its behavior is
consistent with Version 2. The modifyOutgoingSerializationContent
method stores the data in properties consistent with Version 1 of the class. With this
method in place:
Both Version 1 and Version 2 of the class can load instances saved under Version 2a because the property values are stored in the original format of Version 1.
modifyOutgoingSerializationContent
saves the rectangle information asx0
,y0
,width
, andheight
by default, but it also saves the coordinatesx1
,x2
,y1
, andy2
. Because Version 2a includes the properties and values in the same format as Versions 1 and 2, Version 2a can load an instance of any version.
classdef Rectangle < matlab.mixin.CustomElementSerialization % Version 2a properties x0 y0 width height end methods function obj = Rectangle(x1,y1,x2,y2) obj.x0 = x1; obj.y0 = y1; obj.width = x2 - x1; obj.height = y2 - y1; end end methods(Static) function modifyOutgoingSerializationContent(sObj,obj) sObj.addNameValue("x1",obj.x0); sObj.addNameValue("x2",obj.x0 + obj.width); sObj.addNameValue("y1",obj.y0); sObj.addNameValue("y2",obj.y0 + obj.height); end end end
With this new version, you can now take advantage of all of the capabilities of
matlab.mixin.CustomElementSerialization
. To check the compatibility,
create an instance of Rectangle
under Version
2a.
test = Rectangle(1,1,4,6)
test = Rectangle with properties: x0: 1 y0: 1 width: 3 height: 5
Save the instance. modifyOutgoingSerializationContent
uses the
width
and height
properties to define the
second
vertex.
save("yourfilepath/RectV2a.mat","test")
Clear the instance, and then load it under Version 1.
clear test load("yourfilepath/RectV2a.mat","test") test
test = Rectangle with properties: x1: 1 y1: 1 x2: 4 y2: 6
Private Properties with the Same Name in Class Hierarchies
Classes in a hierarchy that define private properties with the same name require
special handling when serializing and deserializing with loadobj
and
saveobj
. The Animal
class and its subclass
Pet
both define a private property named ID
. To
handle both properties:
The
saveobj
method ofAnimal
saves itsID
property in the outgoing structure under the name ofAnimalID
to avoid conflicting with theID
property ofPet
.The
loadobj
methods of both classes pass the value ofAnimalID
to the constructor to recreate theID
property ofAnimal
.
classdef Animal properties Species end properties(Access = private) ID end methods function obj = Animal(Species,ID) obj.Species = Species; obj.ID = ID; end function s = saveobj(obj) s.Species = obj.Species; s.AnimalID = obj.ID; end end methods (Static) function obj = loadobj(s) if isstruct(s) obj = Animal(s.Species,s.AnimalID); else obj = s; end end end end
classdef Pet < Animal properties OwnerName end properties(Access = private) ID end methods function obj = Pet(Species,AnimalID,OwnerName,ID) obj@Animal(Species,AnimalID); obj.OwnerName = OwnerName; obj.ID = ID; end function s = saveobj(obj) s = saveobj@Animal(obj); s.OwnerName = obj.OwnerName; s.ID = obj.ID; end end methods(Static) function obj = loadobj(s) if isstruct(s) obj = Pet(s.Species,s.AnimalID,s.OwnerName,s.ID); else obj = s; end end end end
The matlab.mixin.CustomElementSerialization
mixin enables you to
reference private properties with the same name by preceding the property name with the
name of the defining class and a dot. You can use this convention to transition classes
with private property overlap to use the mixin instead of saveobj
and
loadobj
.
For example, the following revised Animal
class inherits from the
mixin and implements a modifyIncomingSerializationContent
method. The
saveobj
method of the original Animal
stores its
ID
property as AnimalID
. The
modifyIncomingSerializationContent
method checks for an
AnimalID
field in the incoming content. If
AnimalID
is part of the serialized content, the
modifyIncomingSerializationContent
method renames the property to
Animal.ID
. The rename
method uses the
className.propertyName
syntax that is required for private
properties. (For more information, see the description for rename
in
matlab.serialization.ElementSerializationContent
.)
classdef Animal < matlab.mixin.CustomElementSerialization properties Species end properties (Access = private) ID end methods function obj = Animal(Species,ID) obj.Species = Species; obj.ID = ID; end end methods(Static) function modifyIncomingSerializationContent(sObj) if sObj.hasNameValue("AnimalID") sObj.rename("AnimalID","Animal.ID"); end end end end
Pet
class implements a
modifyIncomingSerializationContent
method that calls the superclass
method to process the superclass ID
property. To enable the older
version of the class to deserialize objects saved under the new definition,
Pet
implements modifyOutgoingSerializationContent
to
save the superclass ID
property as AnimalID
.
classdef Pet < Animal properties OwnerName end properties(Access = private) ID end methods function obj = Pet(Species,AnimalID,OwnerName,ID) obj@Animal(Species,AnimalID); obj.OwnerName = OwnerName; obj.ID = ID; end end methods(Static) function modifyOutgoingSerializationContent(sObj,~) sObj.addNameValue("AnimalID",sObj.getValue("Animal.ID")); sObj.remove("Animal.ID"); end function modifyIncomingSerializationContent(sObj) modifyIncomingSerializationContent@Animal(sObj) end end end
Maintaining Existing loadobj
and saveobj
Implementations
In some cases, existing designs using loadobj
and
saveobj
cannot be easily transitioned to a
matlab.mixin.CustomElementSerialization
design without significant
revision of existing classes. For example:
The
loadobj
method of an existing class only accepts a structure as input. Deserializing an object under the old definition might cause warnings. To forceloadobj
to deserialize the content as a structure, you can usemodifyOutgoingSerializationContent
to add a property that is not part of the original class definition. The disadvantage to this method is that the added property is now stored, even though it has no meaning in either version of the class.The
loadobj
method can only deserialize data from a format other than an object or a structure. For example, a class could usesaveobj
to save property values in a table, and the correspondingloadobj
can only accept a table as input. The methods ofmatlab.mixin.CustomElementSerialization
only support object data, so data from the older version of the class would be inaccessible. In this case, the only workaround is to revise how the existing class definition serializes data.
In cases like these, maintaining your existing loadobj
and
saveoobj
implementations might be preferable to what would be
required to transition to matlab.mixin.CustomElementSerialization
.
See Also
matlab.mixin.CustomElementSerialization
| matlab.serialization.ElementSerializationContent
| matlab.serialization.SerializationContext