简体   繁体   中英

Why does this code throw a ClassCastException?

The code below is from my App in Android Studio and it runs fine:

static void removeViewParent(ImageView image) {
    if (image.getParent() != null) ((ViewGroup) image.getParent()).removeView(image);
}

I tried to reproduce it like following similar idea: since the original ones: abstract class ViewGroup and ImageView inherit same super class View and its method getParent() returns an interface reference. Using IntelliJ IDEA I made a similar reproduction for casting purposes in the following code:

interface ViewParent {
    ViewParent getParentView();
}

class View {
    ViewParent getParent() {
        return () -> null;
    }
}

abstract class ViewGroup extends View implements ViewParent {
    void removeView(ImageView image) {
        System.out.println(image); //Just for debugging.
    }
}

class ImageView extends View {
}

class RunMain {
    public static void main(String[] args) {
        ImageView image = new ImageView();
        ((ViewGroup) image.getParent()).removeView(image);
    }
}

Exception in thread "main" java.lang.ClassCastException: View$$Lambda$1/1078694789 cannot be cast to ViewGroup.

EDITED: The original class View in Android SDK is actually returning a ViewParent so how it's possible?

在此处输入图片说明 在此处输入图片说明

Why I'm getting a ClassCastException?

both ViewGroup and ImageView are subclasses of View but they have no direct inheritence relationship (super-sub classes). One cannot cast between two subclasses. only between super class and its sub class (either up casting or down casting)

assuming the hierarchy tree is given (meaning you can't change it) then to make this work you need to explicitly ask on the type of the getParent() return value

if (image.getParent() != null && image.getParent() instanceof ViewGroup) { 
   ((ViewGroup) image.getParent()).removeView(image);
}

This will make getParent() return an instance of ViewGroup hence its implementation with ParentView Interface makes ViewGroup compatible then no ClassCastException .

class View {
    ViewParent getParent() {
        return new ViewGroup() {
            @Override
            public ViewParent getParentView() {
                return null;
            }
        };
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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