Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics - Why is this method call considered an unchecked conversion

The following code examples compiles but with a compiler warning

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}

class SubArrayList<T> extends ArrayList{}

class ZiggyTest2{

    public static void main(String[] args){                 
        ArrayList<Animal> nums = new SubArrayList<Animal>();

    }

    public static void testMethod(ArrayList<Animal> anim){
        System.out.println("In TestMethod");
    }
}   

When i compile the above i get the following warning

Note: ZiggyTest2.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Or if i compile it with -Xlint:unchecked i get the following warning

ZiggyTest2.java:12: warning: [unchecked] unchecked conversion
found   : SubArrayList<Animal>
required: java.util.ArrayList<Animal>
                ArrayList<Animal> nums = new SubArrayList<Animal>();
                                         ^
1 warning

If i change the initialisation of nums to

List<Animal> nums = new ArrayList<Animal>(); 

then i dont get any warnings.

Why are they behaving differently. ArrayList is a subtype of List and SubArrayList is a subtype of ArrayList so i was expecting the instantiation to be the same.

Thanks.

Edit

Also if i call the method and pass it an reference initialised generically it also produces a warning.

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}

class SubArrayList<T> extends ArrayList{}

class ZiggyTest2{

    public static void main(String[] args){                 
        SubArrayList<Animal> nums = new SubArrayList<Animal>();
        testMethod(nums);

    }

    public static void testMethod(ArrayList<Animal> anim){
        System.out.println("In TestMethod");
    }
}

I thought compiler warnings will only appear if you mix generic code with non-generic code.

like image 875
ziggy Avatar asked Jan 19 '26 09:01

ziggy


1 Answers

Your SubArrayList<T> class only extends ArrayList (essentially ArrayList<?>), and not ArrayList<T>, making a cast from SubArrayList<T> to ArrayList<T> unchecked.

If you change it to class SubArrayList<T> extends ArrayList<T> {}, you will not have the problem anymore :)

like image 171
Romain Avatar answered Jan 20 '26 22:01

Romain



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!