Разница между общими параметрами Java - PullRequest
2 голосов
/ 07 июля 2010

В чем разница между передачей в универсальном параметре некоторого универсального класса с и без его универсального параметра?

Пример:

Простой родовой класс:

public class Foo<T> { /*...*/ }

Простой класс, который расширяет простой универсальный класс, устанавливая универсальный параметр в некоторый нерелевантный тип:

public class FooFoo extends Foo<Type1> { /*...*/ }

Еще один общий класс

public class Bar<T> extends FooFoo { /*...*/ }

Наш базовый класс, которому в качестве универсального параметра требуется нечто, расширяющее класс Foo

public class TestFooClass<T extends Foo<?>> { /*...*/ }

И вопрос, в чем разница между этими двумя параметрами

public class BarTestOne extends TestFooClass<Bar> { /*...*/ }

public class BarTestTwo extends TestFooClass<Bar<?>> { /*...*/ }

Задача

Class<T> class = (Class<T>) ((Foo)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

В первом случае код работает, во втором - нет.

Ответы [ 2 ]

3 голосов
/ 08 июля 2010

Похоже, вы пытаетесь определить фактический тип, с которым параметризован TestFooClass?

В этом контексте разница между использованием универсального класса с и без его универсального параметра заключается в том, что getActualTypeArguments () [0] будет:

  1. В первом случае укажите экземпляр класса, представляющий необработанный тип
  2. Во втором случае предоставьте экземпляр ParameterizedType (таким образом, можно получить ClassCastException). Если вы вызовете getRawType () для этого ParameterizedType, вы получите Class, представляющий необработанный тип.

Это:

BarTestOne one = new BarTestOne();
BarTestTwo two = new BarTestTwo();

Class<?> clazz1 = (Class<?>) ((ParameterizedType) one.getClass().getGenericSuperclass()).getActualTypeArguments()[0];       
Class<?> clazz2 = (Class<?>) ((ParameterizedType) ((ParameterizedType) two.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getRawType();

System.out.println(clazz1.equals(clazz2));

Это вернет true .

Увы, любой более глубокий ответ за пределами моих знаний о дженериках.

0 голосов
/ 07 июля 2010

Bar означает Bar<Object>, а Bar<?> - нет.Например, если у вас есть List, вы можете добавить к нему, если у вас есть List<?>, которого вы не можете, потому что компилятор не знает, совместим ли ваш объект с «фактическим универсальным типом»объект.

Что касается кода отражения, я не знаю.Он говорит getClass(), что зависит от объекта, на котором вы его вызываете;в этом случае объект явно this ... Откуда этот код называется?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...