ArrayList无法转换为扩展ArrayList的自定义类

6

我有一个如下所示的类:

public class JsonHistoryList extends ArrayList<JsonHistory> implements Serializable{}

我希望使用Intent传递它

timerService.putExtra(TimerService.ACTIVITY_LIST_ARG, activities);

但是在我接收到它之后(见下文)
JsonHistoryList temp = (JsonHistoryList) intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);

在我的服务中,它给了我一个异常:
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.epstim.captime.jsonmodel.JsonHistoryList

我不理解为什么Java无法处理该操作。

我已经根据服务更改了我的代码:

ArrayList<JsonHistory> temp = (ArrayList<JsonHistory>) intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);
activities.addAll(temp);

它成功了。


尝试清理你的项目并重新运行。 - Tushar Gogna
活动是什么?你确定是 JsonHistoryList 吗? - user902383
请打印 temp.getClass().toString() 并告诉我们它是什么。 - Stephen C
activities 是一个 JsonHistoryList 列表? - BatScream
5个回答

9

在内部,Android会将每个extra放入一个特殊的Map中,并不记录您希望如何打包它。

在某些时候,Android会将您的extras转换为parcel,它会通过检查每个对象类型(因为它并不记得您想要的方式)来进行操作。

Parcel支持writeList和writeSerializable,而您的JsonHistoryList也是两者(可序列化列表和可序列化本身的列表)。

因此,Android打包的过程如下:

for (Object object : extras) {
   //... check for other types here
   } else if (object instanceof List) {
     parcel.writeList(object); // This what happens in your case and will be unparcelled into arraylist
   } else if (object instanceof Serializable) {
     parcel.writeSerializable(object); // What you really want, but percelling never will get here
   }
}

如果您想保留列表,您需要创建一个可序列化的类,它不会扩展arraylist,而是将其包含在内。

public class SuperJsonHistory implements Serializable {
  private JsonHistoryList yourList;
  ...
}

如果您想要保留类型,那么在组合和继承之间选择组合。


你知道 Parcelable 在这个类型检查列表中是在 List 之上吗? 如果可以的话,我更愿意让我的类继承 ArrayList! - rythos42
这刚刚救了我一命。谢谢。 - Jtvd78

1
如果intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);返回ArrayList<JsonHistory>类的对象而不是JSONHistoryList类型的对象,就会发生这种情况。

我们无法强制向下转换父对象。

考虑您的示例:

public class JsonHistoryList extends ArrayList implements Serializable{ public int someField ;// 可以是任何内容 }

为了简单起见,如果您的getSerializableExtra();返回new ArrayList<JsonHistory>(),当您尝试将其向下转换为JsonHistoryList时,它无法进行转换,因为无法确定someField值。


但是为什么intent.getSerializableExtra();返回的是ArrayList而不是JsonHistoryList呢? - Averus
我认为你的 activities 是类型为 ArrayList<JsonHistory>,这就是为什么它返回了一个 ArrayList - Anoop
在这两个文件中:private JsonHistoryList activities; 第一个是Activity,第二个是Service。 - Averus

0

我们无法将超类对象强制转换为子类对象。

只有当要转换的对象通过IS-A关系时,才能进行强制转换。

您可以查看此链接。它将消除所有疑虑 从超类到子类的显式转换


0
所以如果 JsonHistoryList extends ArrayList,那么一个 JsonHistoryList 是一个 ArrayList,但是一个 ArrayList 不一定是一个 JsonHistoryList。你期望得到自己的子类,但实际上并不是这样的。

0

我遇到了和你一样的问题,我只是添加了一个实现Serializable接口的封装类:

public class JsonHistoryListWrapper implement Serializable {
    JsonHistoryList jsonHistoryList;

    private JsonHistoryListWrapper(JsonHistoryList jsonHistoryList) {
        this.jsonHistoryList = jsonHistoryList;
    }

    public static JsonHistoryListWrapper wrapper(JsonHistoryList jsonHistoryList) {
        return new JsonHistoryListWrapper(jsonHistoryList);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接