Я использую Java 8. В моем дизайне есть несколько простых классов, которые моделируют параметры значений, такие как FloatParameter
или EnumParameter<E>
. A имеют общий универсальный суперкласс этих классов (GenericParameter<T>
), который реализует имя параметра и его значение по умолчанию. Подклассы реализуют другие атрибуты, специфичные для них, такие как диапазон в случае FloatParameter
.
Более того, я хочу работать с типами параметров независимо от их конкретного типа. Но я все еще хочу связать типы так, чтобы они были подтипами GenericParameter<T>
. Для этого я создал такой метод, как process(Class<? extends GenericParameter<?>> paramType)
.
Теперь проблема в том, что EnumParameter.class
нельзя присвоить переменной типа Class<? extends GenericParameter<?>>
, а FloatParameter.class
может.
Далее я привожу код для классов, чтобы сделать его более понятным и воспроизводимым:
public class GenericParameter<T> {
protected String name;
protected T defaultValue;
}
public class FloatGenericParameter extends GenericParameter<Float> {
...
}
public class TypedGenericParameter<T> extends GenericParameter<T> {
...
}
Class<? extends GenericParameter<?>> fgpc = FloatGenericParameter.class; // ok
Class<? extends GenericParameter<?>> tgpc = TypedGenericParameter.class; // error: incompatible types: Class<TypedGenericParameter> cannot be converted to Class<? extends GenericParameter<?>>
Class<? extends GenericParameter> tgpc2 = TypedGenericParameter.class; // warning: [rawtypes] found raw type: GenericParameter
Наконец, при использовании неуниверсального базового класса проблем нет:
public class Parameter {
....
}
public class FloatParameter extends Parameter {
...
}
public class TypedParameter<T> extends Parameter {
...
}
Class<? extends Parameter> fpc = FloatParameter.class; // ok
Class<? extends Parameter> tpc = TypedParameter.class; // ok
Пожалуйста, у вас есть предложения?
Я могу использовать process(Class<?> paramType)
в качестве обходного пути или выполнять приведения типов, но я хотел извлечь выгоду из статической проверки типов компилятором.
РЕДАКТИРОВАТЬ:
Я хотел бы использовать приведение при регистрации фабрик, которые производят компоненты GUI для каждого типа параметра. Код выглядит так:
addParameterComponentFactory(EnumParameter.class, new ParameterComponentFactory() { ... })
В таком случае компилятор проверит добавленный тип параметра во время компиляции. Также код будет более понятным.
РЕДАКТИРОВАТЬ 2:
В настоящее время я использую предложенный подход, чтобы ввести параметр типа для метода addParameterComponentFactory
. Подпись выглядит так:
public static <P extends GenericParameter<?>> addParameterComponentFactory(Class<P> clazz, ParameterComponentFactory pcf)
С помощью этого определения я могу указать TypedParameter.class
(EnumParameter.class
- также один параметр типа), а также получить проверку статического типа.
TypedGenericParameter.class
вClass<? extends GenericParameter<?>>
? - person Ján Halaša   schedule 19.09.2017