这是一个普通的JAVA问题。在android中,有一个接口Parcelable
:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
我们需要实现2个函数describeContents()
和writeToParcel
。
(问题)
除此之外,我们还需要将Parcelable.Creator<T>
接口实现为名为CREATOR的静态字段。
一切都是直截了当的。现在我想创建一个具有Parcelable类类型的通用类:
public class ShushContainer<T extends Parcelable> implements Parcelable
我能够实现Parcelable。我可以调用T
的{{1}}函数。但是,我无法访问静态CREATOR字段。
writeToParcel
答案 0 :(得分:1)
您需要<T extends Parcelable>
而不是<T extends ShushContainer<T> & Parcelable>
,而是指定T
为ShushContainer
,以便您可以访问方法和变量。
public class ShushContainer<T extends ShushContainer<T> & Parcelable>
implements Parcelable
以下是使用Serializable
class Sample<T extends Sample<T> & Serializable> implements Serializable {
public static int CONST = 0;
public void foo()
{
T.CONST = 5;
}
}
<强>更新强>
如果我理解正确,则另一个实现Parcelable
的类具有CREATOR
您正在尝试静态变量的动态多态性,这是不可能的。
示例如何显示失败
public class Base {
public static int count = 10;
}
public class Child extends Base {
public static int count = 20;
}
class Sample<T extends Base> {
T t = null;
public void printCount() {
System.out.println(T.count);
}
public Sample(T t) {
this.t = t;
}
public static void main(String[] args) {
Sample<Child> sample = new Sample<Child>(new Child());
Sample<Base> sample1 = new Sample<Base>(new Base());
sample.printCount();//Child value printed as 10
sample1.printCount();//Same for parent value printed as 10
}
}
此程序失败,因为静态字段绑定到Class而不是实例,因此如果您访问count
的值,则Base
有两个单独的Child
{}} Base
那么它总是10。
您可以使用反射来检查CREATOR
字段是否存在并访问它。没有对象或类对象,这是不可能的。
或者您可以使用TypeToken
执行以下操作class Sample<T extends Serializable> implements Serializable {
public int abc = 0;
public void foo() {
}
public static void main(String[] args) throws SecurityException, NoSuchFieldException {
TypeToken<Sample<Integer>> token = new TypeToken<Sample<Integer>>() {
};
Class<?> t = token.getRawType();
Field field = t.getDeclaredField("abc");
field.setAccessible(true);
System.out.println(field.getName());
}
}
答案 1 :(得分:0)
这并没有回答您关于如何访问静态CREATOR属性的问题,但是您不需要访问此属性实现Parcelable。见下面的例子:
public class TestModel<T extends Parcelable> implements Parcelable {
private List<T> items;
private String someField;
public List<T> items() {
return items;
}
public void setItems(List<T> newValue) {
items = newValue;
}
public String someField() {
return someField;
}
public void setSomeField(String newValue) {
someField = newValue;
}
//region: Parcelable implementation
public TestModel(Parcel in) {
someField = in.readString();
int size = in.readInt();
if (size == 0) {
items = null;
}
else {
Class<?> type = (Class<?>) in.readSerializable();
items = new ArrayList<>(size);
in.readList(items, type.getClassLoader());
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(someField);
if (items == null || items.size() == 0)
dest.writeInt(0);
else {
dest.writeInt(items.size());
final Class<?> objectsType = items.get(0).getClass();
dest.writeSerializable(objectsType);
dest.writeList(items);
}
dest.writeInt(items.size());
for(int i=0;i<items.size();i++)
items.get(i).writeToParcel(dest, flags);
}
public static final Parcelable.Creator<TestModel> CREATOR = new Parcelable.Creator<TestModel>() {
public TestModel createFromParcel(Parcel in) {
return new TestModel(in);
}
public TestModel[] newArray(int size) {
return new TestModel[size];
}
};
//endregion
}