Итак, у нас есть общий метод, подобный этому, который является частью инициализации внедрения зависимости:
public static <TS, TI extends TS> void registerTransient(
Class<TS> serviceClass, Class<TI> implementationClass)
{
//
}
В какой-то момент мы обнаружили случай, когда класс не обязательно должен присутствовать. И это класс реализации, который мы будем вводить множественно (таким образом, класс обслуживания такой же, как и класс реализации). Естественно, вы бы написали это так:
Class<?> clazz = Class.forName("com.acme.components.MyPersonalImplementation");
registerTransient(clazz, clazz);
У IDEA нет проблем с этим, но javac жалуется:
error: method registerTransient in class TestTrash cannot be applied to given types;
required: Class<TS>,Class<TI>
found: Class<CAP#1>,Class<CAP#2>
reason: inferred type does not conform to declared bound(s)
inferred: CAP#2
bound(s): CAP#1
where TS,TI are type-variables:
TS extends Object declared in method <TS,TI>registerTransient(Class<TS>,Class<TI>)
TI extends TS declared in method <TS,TI>registerTransient(Class<TS>,Class<TI>)
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Object from capture of ?
Что дает? Метод требует, чтобы второй параметр был подклассом первого. Независимо от того, к какому классу относится ?
, это один и тот же объект класса для обоих параметров, и я думал, что класс всегда можно назначить из самого себя. Это похоже на то, как если бы javac излишне придумывал второй подстановочный тип, чтобы использовать его для второго параметра, а затем сказал: «О, дорогой, у вас здесь есть два подстановочных знака, поэтому я не могу сказать, назначается ли один из другого».