简体   繁体   English

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

[英]ArrayList cannot be cast to custom class extending ArrayList

I have class mentioned below: 我有下面提到的课程:

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

I wish to pass it through intent using 我希望通过意图使用它

timerService.putExtra(TimerService.ACTIVITY_LIST_ARG, activities);

But after I receive it (way below) 但在我收到它之后(下面的方式)

JsonHistoryList temp = (JsonHistoryList) intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG);

in my service it gives me exception: 在我的服务中它给了我例外:

Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.epstim.captime.jsonmodel.JsonHistoryList

I don't understand why java can't handle that operation. 我不明白为什么java无法处理该操作。

I've changed my code in service to: 我已将服务代码更改为:

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

And it worked. 它奏效了。

In the internals, android puts every extra in a special Map and doesn't record how exactly you want it parcelled. 在内部,android将所有额外内容放在一个特殊的Map中,并且不记录你想要它的确切分区。

At some point android will flattern your extras into parcel, and it will do so by checking each object type (since, as I said, it doesn't remember how you want it). 在某些时候,android会将你的额外内容扁平化为parcel,它会通过检查每个对象类型来实现(因为,正如我所说,它不记得你想要它)。

Parcel supports both writeList and writeSerializable and your JsonHistoryList is also both (list of serializables and a serialisable itself) Parcel支持writeList和writeSerializable,您的JsonHistoryList也是(可序列化列表和可序列化本身)

So android parcelling goes like this: 所以android parcelling是这样的:

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
   }
}

If you want to preserve list you need to create a class that will be serializable and won't extend arraylist but will contain it inside. 如果你想保留列表,你需要创建一个可序列化的类,不会扩展arraylist但会包含它。

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

So composition over inheritance in case you want to preserve type 因此,如果要保留类型,请继承组合

This happens if intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG); 如果intent.getSerializableExtra(TimerService.ACTIVITY_LIST_ARG); returns an object of class ArrayList<JsonHistory> and not an object of type JSONHistoryList . 返回类ArrayList<JsonHistory>的对象,而不是JSONHistoryList类型的对象。

We cannot forcefully downcast a parent object. 我们无法强制转发父对象。

Consider your example,say 比如你的例子

public class JsonHistoryList extends ArrayList implements Serializable{ public int someField ;// can by anything } 公共类JsonHistoryList扩展ArrayList实现Serializable {public int someField; //可以通过任何东西}

For simplicity, if your getSerializableExtra(); 为简单起见,如果你的getSerializableExtra(); returns, new ArrayList<JsonHistory>() , when you try to downcast this to JsonHistoryList , it cannot cast so because someField values cannot be determinied 返回, new ArrayList<JsonHistory>() ,当你试图将它向下转换为JsonHistoryList ,它无法JsonHistoryList转换,因为someField值无法确定

we cannot cast a superclass object into a sub-class object. 我们不能将超类对象强制转换为子类对象。

Cast is only possible if object which is to be casted passes the IS-A relationship. 只有当要转换的对象通过IS-A关系时才可以进行转换。

you can have a look at this link.It will clear all doubts explicit casting from super class to subclass 你可以看看这个链接。它将清除所有怀疑从超类到子类的显式转换

So if JsonHistoryList extends ArrayList , then a JsonHistoryList is an ArrayList but an ArrayList is not necessarily a JsonHistoryList . 因此,如果JsonHistoryList extends ArrayList ,那么JsonHistoryList是一个ArrayList但是ArrayList不一定是JsonHistoryList You expected your own subclass, but that's not what you got back. 你期望自己的子类,但这不是你得到的。

I met the same problem as you, I just add a wrapper class which implements Serializable: 我遇到了和你一样的问题,我只是添加一个实现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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM