【发布时间】:2015-07-26 06:03:26
【问题描述】:
Edit #1在问题底部添加。
我在一个Android项目中得到了ClassCastException,但是问题似乎出在Java领域,所以我写了以下SSCCE。在这个 SSCCE 中,我在 PVC parentViewHolder = (PVC) holder; 上收到以下异常:
Exception in thread "main" Overridden onBindViewHolder in my ExpandableRecyclerAdapter called.
java.lang.ClassCastException: practice_programs.inheritance.class_cast_to_super.RecyclerView$ViewHolder cannot be cast to practice_programs.inheritance.class_cast_to_super.ParentViewHolder
at practice_programs.inheritance.class_cast_to_super.ExpandableRecyclerAdapter.onBindViewHolder(ExpandableRecyclerAdapter.java:9)
at practice_programs.inheritance.class_cast_to_super.ExpandableRecyclerAdapter.main(ExpandableRecyclerAdapter.java:15)
正如您在给出的代码中看到的,我们正在尝试将 RecyclerView.ViewHolder 强制转换为 ParentViewHolder(实际上是 RecyclerView.ViewHolder 的子类)
虽然我知道超类不能转换为子类,但我的困惑如下:
我正在处理的 Android 项目实际上使用 this ExpandableRecyclerView 实现作为库项目。 在这个项目中,发生同样的事情不会产生任何问题。 参见Line # 146 on in this class,其中RecyclerView.ViewHolder 被转换为ParentViewHolder,you can see on Line#19 here 扩展RecyclerView.ViewHolder。
SSCCE:
public class ExpandableRecyclerAdapter<PVC extends ParentViewHolder> extends RecyclerView.Adapter{
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
System.out.println("Overridden onBindViewHolder in my ExpandableRecyclerAdapter called.");
PVC parentViewHolder = (PVC) holder;//EXCEPTION***************************************
super.onBindViewHolder(parentViewHolder, position);
}
public static void main (String [] args) {
new ExpandableRecyclerAdapter().onBindViewHolder(new RecyclerView.ViewHolder(), 1);
}
}
ParentViewHolder.java
public class ParentViewHolder extends RecyclerView.ViewHolder {
String string = "XAR!";
}
RecyclerView.java
public class RecyclerView {
public static class ViewHolder {}
public static class Adapter {
public void onBindViewHolder(ViewHolder viewHolder, int position) {
System.out.println("onBindViewHolder of RecyclerView.ViewHolder called.");
System.out.println("The string of the passed viewHolder is " + ((ParentViewHolder) viewHolder).string);
}
}
}
_______________________________________________________________________________
编辑 1:
另外一条可能很重要的信息是,根据我的需要,我对ExpandableRecyclerAdapter做了一点小小的改动:
第 119 行和第 123 行是
onCreateViewHolder方法的方法体中的方法调用,它接收参数int viewType。我在 Line#119 和 Line#123 上对onCreateParentViewHolder和onCreateChildViewHolder的调用中添加了这个viewType参数。按照^,我将
int viewType参数添加到Line#187和Line#195的对应方法声明中
【问题讨论】:
-
据我所见,他们的版本在传递错误的类型时应该会导致异常,但我猜想在他们的项目中根本不会发生这种情况,因为要么总是在传递之前检查类型,要么是其他类不变量。
-
@NESPowerGlove 你能看到我的编辑,并告诉我你是否认为我所做的更改会导致问题?
-
这是两个抽象方法,我不知道它们实现的所有位置,但是在这两个抽象方法的每个实现中添加额外的参数以用作
onCreateViewHolder之类的保护应该只要您传递的守卫与传递的类型匹配,就不会破坏任何我想像的东西。当他们可以只做instanceof检查时,将 int 枚举作为保护来识别其他参数类型的想法有点奇怪。 -
我的意思是您检查以确定持有人类型的值,以防止错误地转换持有人类型。
-
我可以通过我的回答中已经说明的其他方式提供帮助吗?您的文字(粗体,关于铸造)是错误的 - 铸造是可能的。问题是由于在适配器视图中放置了错误类的对象引起的,唯一可以给出的建议(除非您告诉我们您要完成的工作)是 - 不要将对象转换为它们不具有的类型.
标签: java android inheritance casting classcastexception