非序列化父类的序列化的子类 [英] Serializable subclass of non-serializable parent class

查看:129
本文介绍了非序列化父类的序列化的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打同位置的机器人/ Java的一个子类

的串行化的砖墙

位置不是可序列化。 我有一个第一子类,称为FALocation不具有任何实例变量。我已经宣布它序列化。

然后,我有一个第二类称为航点,看起来是这样的:

 公共类航点扩展FALocation实现Serializable {

    / **
     *
     * /
    私有静态最后长的serialVersionUID = 1L;

    / *类变量********************************************** ********* /
    私有静态诠释CLASS_VERSION = 1; //用于版本包裹

    / *实例变量********************************************** ****** /
    私人瞬态字符串类型= DataHelper.PT_TYPE_US;
    私人瞬态字符串的国家;
    私人瞬态字符串名称= NULL;
    私人瞬态字符串描述= NULL;
    私人短暂INT海拔= 0;
    私人瞬态INT人口= 0; //再思考,增加以匹配数据库结构

    / *构造*********************************************** *********** /
    公共航点(){
        超();
    }

    公共航点(双纬度,双经度,字符串名称,字符串描述){
        超(纬度,经度);
        this.setName(名称);
        this.setDescription(介绍);
    }

    公共航点(地点L){
        超级(升);
    }

    公共航点(字符串提供商){
        超(供应商);
    }


    / *实现Serializable * /
    私人无效的writeObject(java.io.ObjectOutputStream中出)抛出IOException异常{
        Log.v(DroidFA,连载\%s \的(V%D),Waypoint.class.getSimpleName(),CLASS_VERSION);
        out.writeInt(CLASS_VERSION);

        out.writeObject(类型);
        out.writeObject(国家);
        out.writeObject(名称);
        out.writeObject(介绍);
        out.writeInt(海拔);
        out.writeInt(人口);
    }

    私人无效的readObject(java.io.ObjectInputStream中的)抛出IOException异常,ClassNotFoundException异常{

        INT serialClassVersion = in.readInt();
        Log.v(DroidFA,Deserialising \%s \的(V%D),Waypoint.class.getSimpleName(),serialClassVersion);

        类型=(字符串)in.readObject();
        国家=(字符串)in.readObject();
        名称=(字符串)in.readObject();
        说明=(字符串)in.readObject();
        仰角= in.readInt();
        人口= in.readInt();
    }
}
 

序列化工作正常。

Deseriamization产生followwing异常(腿部对象包含一个航点):

  10-05 13:50:35.259:WARN / System.err的(7867):java.io.InvalidClassException:android.location.Location; IllegalAccessException
10-05 13:50:35.267:WARN / System.err的(7867):在java.io.ObjectInputStream.resolveConstructorClass(ObjectInputStream.java:2010)
10-05 13:50:35.267:WARN / System.err的(7867):在java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2095)
10-05 13:50:35.267:WARN / System.err的(7867):在java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:929)
10-05 13:50:35.267:WARN / System.err的(7867):在java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285)
10-05 13:50:35.278:WARN / System.err的(7867):在java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240)
10-05 13:50:35.278:WARN / System.err的(7867):在com.droidfa.navigation.Leg.readObject(Leg.java:262)
... / ...
 

解决方案

它是绝对必要的序列化的定位?也许你可以将其标记为短暂的,反序列化对象后,动态获取它。 (无论如何,从文档):

  

问:如果类A没有实现Serializable但是子类乙实现Serializable,将A类的字段时B被序列化进行序列化

     

答:序列化对象只有字段写出来和恢复。该对象可以被恢复仅当它有一个无参数的构造函数,将初始化非序列化父类型的字段。如果子类访问超类的就可以实现的writeObject和readObject以保存和恢复状态的状态。

因此​​,如果子类可以访问其非序列化的超类(ES)的领域它可以使用的writeObject和readObject协议来实现序列化。否则,会出现,这将是不可能的序列字段。

I am hitting a brickwall with serialization of a subclass of Location in android/java

Location is not serializable. I have a first subclass called FALocation that does not have any instance variables. I have declared it serializable.

Then I have a second class called Waypoint that looks like this:

public class Waypoint extends FALocation implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    /* Class variables *******************************************************/
    private static int CLASS_VERSION=1; //Used to version parcels

    /* Instance variables ****************************************************/
    private transient String type=DataHelper.PT_TYPE_US;
    private transient String country; 
    private transient String name=null;
    private transient String description=null;
    private transient int elevation = 0;
    private transient int population = 0; // Afterthought, added to match the DB structure

    /* Constructors **********************************************************/    
    public Waypoint() {
        super();
    }

    public Waypoint(double lat, double lon, String name, String description) {
        super(lat, lon);
        this.setName(name);
        this.setDescription(description);
    }

    public Waypoint(Location l) {
        super(l);
    }

    public Waypoint(String provider) {
        super(provider);
    }


    /* Implementing serializable */
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        Log.v("DroidFA", "Serialising \"%s\" (v%d).", Waypoint.class.getSimpleName(), CLASS_VERSION);
        out.writeInt(CLASS_VERSION);

        out.writeObject(type);
        out.writeObject(country);
        out.writeObject(name);
        out.writeObject(description);
        out.writeInt(elevation);
        out.writeInt(population);
    }

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {

        int serialClassVersion = in.readInt();
        Log.v("DroidFA", "Deserialising \"%s\" (v%d).", Waypoint.class.getSimpleName(),serialClassVersion);

        type = (String) in.readObject();
        country = (String) in.readObject();
        name = (String) in.readObject();
        description = (String) in.readObject();
        elevation = in.readInt();
        population = in.readInt();
    }
}

Serialization works fine.

Deseriamization produces the followwing exception (the leg object contains a waypoint).:

10-05 13:50:35.259: WARN/System.err(7867): java.io.InvalidClassException: android.location.Location; IllegalAccessException
10-05 13:50:35.267: WARN/System.err(7867):     at java.io.ObjectInputStream.resolveConstructorClass(ObjectInputStream.java:2010)
10-05 13:50:35.267: WARN/System.err(7867):     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2095)
10-05 13:50:35.267: WARN/System.err(7867):     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:929)
10-05 13:50:35.267: WARN/System.err(7867):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285)
10-05 13:50:35.278: WARN/System.err(7867):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240)
10-05 13:50:35.278: WARN/System.err(7867):     at com.droidfa.navigation.Leg.readObject(Leg.java:262)
.../...

解决方案

Is it absolutely necessary to serialize the Location? maybe you could mark it as transient, and obtain it dynamically after deserializing the object. (Anyway, from the documentation ) :

Q: If class A does not implement Serializable but a subclass B implements Serializable, will the fields of class A be serialized when B is serialized?

A: Only the fields of Serializable objects are written out and restored. The object may be restored only if it has a no-arg constructor that will initialize the fields of non-serializable supertypes. If the subclass has access to the state of the superclass it can implement writeObject and readObject to save and restore that state.

So, if the subclass has access to the fields of its non-serializable superclass(es) it can use the writeObject and readObject protocol to implement serialization. Otherwise, there will be fields that won't be possible to serialize.

这篇关于非序列化父类的序列化的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆