2

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.

ziggy
  • 15,677
  • 67
  • 194
  • 287

3 Answers3

6

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 :)

Romain
  • 12,679
  • 3
  • 41
  • 54
3

Add a <T> to your ArrayList as in

class SubArrayList<T> extends ArrayList<T>{}
Romain
  • 12,679
  • 3
  • 41
  • 54
2

List is an interface, not a class. ArrayList isn't a subclass of List, simply a class that implements the List interface. SubArrayList is, however, a subclass of ArrayList.

Anthony Grist
  • 38,173
  • 8
  • 62
  • 76