2012-06-28 1 views
6

У меня есть некоторые проблемы с методом с типизированным параметром List, унаследованным от другого (типизированного) класса.Метод с типизированным списком и наследованием

Давайте держать это просто:

public class B<T> { 
    public void test(List<Integer> i) { 
    } 
} 

Класс B имеет бесполезный общий T и тест() требуется в список Integer.

Теперь, если я:

public class A extends B { 
    // don't compile 
    @Override 
    public void test(List<Integer> i) { 
    } 
} 

Я получаю "Тест метод (List) типа A должен переопределить или реализовать метод Supertype" ошибка, что не должно произойти.

Но удаление типа списка работает ... хотя оно не зависит от общего класса.

public class A extends B { 
    // compile 
    @Override 
    public void test(List i) { 

А также определение бесполезного родового ниже, чтобы использовать типизированный лист

public class A extends B<String> { 
    // compile 
    @Override 
    public void test(List<Integer> i) { 

Так что я невежественный, родовые из B не должны иметь никакого влияния на типе списка теста(). Кто-нибудь имеет представление о том, что происходит?

Благодаря

+0

Я считаю, что ваш ответ лежит [здесь] (http://stackoverflow.com/a/502770/248082). – nobeh

+0

Обычно [capital V] 'Void' используется для общих параметров, которые вы не хотите использовать. Например, с использованием 'java.security.PreivilegedAction' без возврата значения (return' null' - это единственная действительная ссылка Void). –

ответ

8

Вы расширяете исходный тип B, а не общий. Необработанный метод не имеет метода test(List<Integer> i), но метод test(List).

Если вы переключитесь на необработанные типы, все генераторы заменяются сырыми, независимо от того, был ли их тип заполнен или нет.

Чтобы сделать это правильно, сделайте

public class A<T> extends B<T> 

Это будет использовать общий тип B<T>, который включает в себя метод, который вы хотите переопределить.

+0

Спасибо. Не совсем логично, так как мы не используем T, но у дженериков Java есть некоторые недостатки дизайна, с которыми мы должны иметь дело. – PomPom

1

При удалении использовать класс без дженериков (и использовать его сырым), все дженерики из методов класса забываются.

По этой причине, когда вы сообщаете общий тип во втором случае, вы получаете его работу.

Это:

class T<G> { 
    public void test(G g); 
} 

в этом случае:

class A extends T { 
} 

будет выглядеть следующим образом:

class T { 
    public void test(Object g); 
} 

Это ява головоломка представлена ​​на Google IO 2011 вы можете посмотреть видео here

+0

Реальная проблема в том, что я не использовал G, а конкретный класс. В любом случае, я получил свой ответ – PomPom

+0

Вы использовали исходный класс. –