我已经为我的自定义类实现了 Parcelable:
public class Tag implements Parcelable {
int id;
int type;
int proficiencyLevel;
HashMap<String, String> translations;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(type);
dest.writeInt(proficiencyLevel);
// if this part is uncommented I get a NullPointerException
/*
dest.writeInt(translations.size());
for (HashMap.Entry<String, String> entry : translations.entrySet()) {
dest.writeString(entry.getKey());
dest.writeString(entry.getValue());
}
*/
}
public static final Parcelable.Creator<Tag> CREATOR = new Parcelable.Creator<Tag>() {
public Tag createFromParcel(Parcel in) {
return new Tag(in);
}
public Tag[] newArray(int size) {
return new Tag[size];
}
};
private Tag(Parcel in) {
id = in.readInt();
type = in.readInt();
proficiencyLevel = in.readInt();
// I've put breakpoint here and it seems to work OK, but then I get a NullPointerException
// deserialize `translations` field
/*int size = in.readInt();
for (int i = 0; i < size; i++) {
String key = in.readString();
String value = in.readString();
translations.put(key, value);
}*/
}
}
现在我从 Activity A 中传递它:
Tag[] tagsList = new Gson().fromJson(tags, Tag[].class);
Intent activityTagsSelectorLauncher = new Intent(this, ActivityTagsSelector.class);
activityTagsSelectorLauncher.putParcelableArrayListExtra("tagsList", new ArrayList<>(Arrays.asList(tagsList)));
startActivityForResult(activityTagsSelectorLauncher, SELECT_TAGS_REQUEST);
并在 Activity B 中像这样接收它:
ArrayList<Tag> tagsList = getIntent().getParcelableArrayListExtra("tagsList");
如果我不写 HashMap<String, String> translations
一切正常 field 。我得到NullPointerException
当 Activity B开始时。我已在构造函数 private Tag(Parcel in) {
中放置断点似乎一切正常,所以我不明白我做错了什么。
最佳答案
你得到 NPE
,因为您没有初始化翻译 Map
:
HashMap<String, String> translations
就像
HashMap<String, String> translations = null;
更改声明并初始化 map :
HashMap<String, String> translations = new HashMap<String, String>();
取消注释后即可使用它
dest.writeInt(translations.size());
for (HashMap.Entry<String, String> entry : translations.entrySet()) {
dest.writeString(entry.getKey());
dest.writeString(entry.getValue());
}
更新:为了澄清发生的情况,您声明了变量但没有初始化它,所以 JVM
确实如此,并翻译成 HashMap<String, String> translations = null
.
Initial Values of Variables
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created
[...] For all reference types, the default value is null.
看一下这个默认初始化表:
Type Default Value
--------- -------------
boolean false
byte (byte) 0
short (short) 0
int 0
long 0L
char \u0000
float 0.0f
double 0.0d
object null <-------------- YAY!
之后,当您尝试使用 translations.size()
获取尺寸时与 null.size()
相同,有你的 NPE
...
更大代码中的另一个场景是您可能不想初始化 translations
,这样您就可以safe-check
你的句子:
dest.writeInt(translations != null ? translation.size() : 0);
关于java - 如果自定义类包含 HashMap 字段,则无法通过 Parcelable 传递自定义类 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30345007/