Java Generics - Почему этот вызов метода считается непроверенным преобразованием - PullRequest
2 голосов
/ 07 декабря 2011

Следующие примеры кода компилируются, но с предупреждением компилятора

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");
    }
}   

Когда я компилирую вышеупомянутое, я получаю следующее предупреждение

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

Или, если я компилирую его с -Xlint:сняв флажок, я получаю следующее предупреждение

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

Если я изменю инициализацию чисел на

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

, тогда я не получу никаких предупреждений.

Почему они ведут себя по-разному.ArrayList является подтипом List, а SubArrayList является подтипом ArrayList, поэтому я ожидал, что экземпляр будет таким же.

Спасибо.

Редактировать

Также, если я вызываю метод и передаю ему ссылку, инициализированную в общем виде, он также выдает предупреждение.

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");
    }
}

Я думал, что предупреждения компилятора появятся, только если вы смешаете универсальный код с неуниверсальным кодом.

Ответы [ 3 ]

6 голосов
/ 07 декабря 2011

Ваш класс SubArrayList<T> распространяется только на ArrayList (по существу ArrayList<?>), но не ArrayList<T>, что делает приведение от SubArrayList<T> до ArrayList<T> неконтролируемым.

Если вы измените его на class SubArrayList<T> extends ArrayList<T> {}, у вас больше не будет проблем:)

3 голосов
/ 07 декабря 2011

Добавьте <T> в ваш ArrayList как в

class SubArrayList<T> extends ArrayList<T>{}
2 голосов
/ 07 декабря 2011

List - это интерфейс, а не класс.ArrayList не является подклассом List, а просто классом, который реализует интерфейс List.SubArrayList, однако, является подклассом ArrayList.

...