Исключить параметр типа java generics
Код:
interface Property<T>
{
T get();
}
class BoolProperty implements Property<Boolean>
{
@Override
public Boolean get()
{
return false;
}
}
class StringProperty implements Property<String>
{
@Override
public String get()
{
return "hello";
}
}
class OtherStringProperty implements Property<String>
{
@Override
public String get()
{
return "bye";
}
public String getSpecialValue()
{
return "you are special";
}
}
используется моим классом:
class Result<P extends Property<X>, X>
{
P p;
List<X> list;
}
Как видите, он имеет два типа параметров P
и X
. Несмотря на это, X
всегда можно вывести из P
, но для этого языка я должен предоставить оба:
Result<BooleanProperty, Boolean> res = new Result<BooleanProperty, Boolean>();
Есть ли какой-либо трюк, чтобы избавиться от параметра типа X
? Я хочу просто использовать
Result<BooleanProperty> res = new Result<BooleanProperty>();
Кроме того, я не хочу потерять информацию о типе и использовать ее как:
Result<OtherStringProperty> res = new Result<OtherStringProperty>();
String spec = res.p.getSpecialValue();
String prop = res.list.get(0);
Ответы
Ответ 1
Есть аналогичный вопрос, ответ на который вы можете найти интересным: fooobar.com/questions/16053/...
По сути, нет никакого реального способа обойти, включая дополнительный родовой тип, потому что компилятор не может знать, какой тип вы используете без него. Я предполагаю, что это побеждает цель вашего подхода, но вы можете попробовать расширить Result
при указании типов - что-то вроде этого:
class BoolResult extends Result<BoolProperty, Boolean> {
// Do stuff
}
Ответ 2
Я бы изменил класс Result
на что-то вроде
class Result<X> {
Property<X> property;
List<X> list;
}
Я не думаю, что компилятор может вывести X
из Property
, так как ваш класс Result
ждет два определения для двух генериков.
Ответ 3
Вы не можете вывести тип, но вы можете добавить дополнительный уровень косвенности:
class BoolProperty implements Property<Boolean>
{
@Override
public Boolean get()
{
return false;
}
}
class Sub<X, P extends Property<X>> {
P p;
List<X> list;
}
class Result<X> extends Sub<X, Property<X>> {
}
Result<Boolean> res = new Result<Boolean>();
List<Boolean> list = res.list;
Boolean b = res.p.get();
List<String> res2 = res.list; // compilation error
Ответ 4
Пробовали ли вы использовать общий шаблон?
class Result<? extends Property<X>>
{
// stuff
}