拦截Parcelable与继承时的ClassCastException

时间:2017-05-19 15:11:07

标签: java android parcelable

我在Android Studio工作,只要我需要Parcelable,我就会自动生成代码。我的情况是我从课程A扩展了超级课程B和课程A。我想通过一个意图类B但是当我拦截它时,我得到一个错误说Caused by: java.lang.ClassCastException: pack.A cannot be cast to pack.B。代码是:

public class A implements Parcelable {

    private String str1;

    protected A(Parcel in) {
        str1 = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str1);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<A> CREATOR = new Creator<A>() {
        @Override
        public A createFromParcel(Parcel in) {
            return new A(in);
        }

        @Override
        public A[] newArray(int size) {
            return new A[size];
        }
    };
}

public class B extends A {

    private String str2;

    protected B(Parcel in) {
        super(in);
    }
}

我对这个错误感到困惑。任何帮助都是apreciated

2 个答案:

答案 0 :(得分:1)

考虑以下场景(使用相同的类,a是super,b是child):

你可以这样做:

A a = new B();

但你不能这样做:

B b = new A();

当您为B加载parcelable但类型为A时,您基本上是这样做的(在不同的代码中,但您基本上告诉机器的是:)

B b = new A()

意味着你现在不能按照自己的意愿这样做。你必须为B创建一个自定义创建者,你可以在其中创建一个B类的parcelable。

对于错误,这是因为创建者是A类型,但是你把它投射到B.这与B b = new A()相同。因此,为了解决它,你必须为B创建一个创建者。

继承是一个有点复杂的话题,因为有很多内容需要跟踪可以投射的内容。

答案 1 :(得分:1)

正如@ n​​jzk2所说,你需要在B类中声明一个新的CREATOR

public class B extends A {

    private String str2;

    protected B(Parcel in) {
        super(in);
        str2 = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeString(str2);
    }

    public static final Creator<B> CREATOR = new Creator<B>() {
        @Override
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

        @Override
        public B[] newArray(int size) {
            return new B[size];
        }
    };
}