Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException in Inheritance - Why?

Following code is throwing ClassCastException :

Exception in thread "main" java.lang.ClassCastException: class Child cannot be cast to class java.util.List (Child is in unnamed module of loader 'app'; java.util.List is in module java.base of loader 'bootstrap') at Test.main(Test.java:20)

I am really not sure why it is behaving like this. I think I have written the correct code.

public class Test {
    public void a(ParentI... ss) {
    }

    public void a(List<ParentI> ss) {
    }


    public <R extends ParentI> R makeParent() {
        ParentI ai = new Child();
        return (R) ai;
    }

    public static void main(String[] args) {
        Test al = new Test();
        al.a(al.makeParent());
    }
}


interface ParentI {
    public void a();
}

class Parent implements ParentI {
    public void a() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    public void a(int t) {
        System.out.println("child");
    }
}

Please help me understand this and how to fix this as well.

like image 238
Sachin Sachdeva Avatar asked Apr 23 '26 14:04

Sachin Sachdeva


2 Answers

The compiler infers the type returned by al.makeParent() according to the a() method being chosen by the method overloading resolution.

Since the method overloading resolution first considers candidates that don't have vararg arguments, only the public void a(List<ParentI> ss) overload is considered, and therefore that's the chosen overload.

The reason public void a(List<ParentI> ss) can accept as its argument the return value of a method that returns R extends ParentI is that there may exist a class that extends ParentI and implements List<ParentI>.

Once the public void a(List<ParentI> ss) overload is chosen, the casting in return (R) ai; causes an attempt to cast a Child instance to a List, which fails in runtime.

If, for example, you changed the definition of Child class to:

class Child extends Parent implements List<ParentI>

your code would run without exception.

like image 104
Eran Avatar answered Apr 26 '26 03:04

Eran


while I do not have the answer as to why the exception is thrown. I have managed to edit the code so that the program runs successfully. the makeParent() method needs to be modified so it is not generic:

public ParentI makeParent() {
    ParentI ai = new Child();
    return ai;
}

which basically is the same as before.

then, the correct overloaded a() is called

like image 31
Sharon Ben Asher Avatar answered Apr 26 '26 04:04

Sharon Ben Asher



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!