У меня есть базовый класс Thing
, который предоставляет некоторые базовые функции, включая получение ссылки на ThingInfo
с параметром типа типа подкласса Thing
. Поскольку в Java нет собственных типов, я не могу использовать это для параметра типа для возвращаемого значения ThingInfo
, поэтому Thing
должен принимать параметр рекурсивного типа, чтобы мы могли вернуть правильный параметризованный ThingInfo
.
interface ThingInfo<T>
{
// just an example method showing that ThingInfo needs to know about
// the type parameter T
T getThing();
}
class Thing<T extends Thing<T>>
{
// I need to be able to return a ThingInfo with the type parameter
// of the sub class of Thing. ie. ThingA.getThingInfo() must return
// a ThingInfo<ThingA>.
// This is where Java would benefit from self types, as I could declare
// the method something like: ThingInfo<THIS_TYPE> getThingInfo()
// and Thing would not need a type parameter.
ThingInfo<T> getThingInfo()
{
return something;
}
}
// example Thing implementation
class ThingA extends Thing<ThingA>
{
}
// example Thing implementation
class ThingB extends Thing<ThingB>
{
}
Пока все в порядке. Этот код работает по мере необходимости.
Мне также нужно представить безопасное отношение типа между Thing
s.
class ThingRelation<X extends Thing<X>, Y extends Thing<Y>>
{
X getParent()
{
return something;
}
Y getChild()
{
return something;
}
}
На самом деле это не так просто, но это демонстрирует необходимость, я думаю. Тем не менее, все это хорошо, ошибок пока нет. Теперь ThingRelation
нужен метод, который принимает аргумент ThingRelation
между Y
и некоторым другим Thing
. Поэтому я меняю ThingRelation
на следующее:
class ThingRelation<X extends Thing<X>, Y extends Thing<Y>>
{
X getParent()
{
return something;
}
Y getChild()
{
return something;
}
<Z extends Thing<Z>> void useRelation(ThingRelation<Y, Z> relation)
{
// do something;
}
}
Но теперь я получаю эту ошибку при компиляции:
type argument Y is not within bounds of type-variable X
where Y,X are type-variables:
Y extends Thing<Y> declared in class ThingRelation
X extends Thing<X> declared in class ThingRelation
Ошибка в строке, начинающейся<Z extends Thing<Z>>....
В чем может быть проблема?
Обновление:Версия javac
— 1.7.0_05
.