泛型工厂的泛型和类型推断

米鲁夫

对于这个问题的英语不好,我们深表歉意。

我想到要创建一种工厂,该工厂只能创建由具体工厂实例类实现的列表中定义的类的实例。首先,我定义了这个接口:

public interface ValuesSystem {

    public interface AllowedValue<T extends Class<? extends SystemValue>>{};

    AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id);

    Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues();

    <T extends SystemValue> T create(AllowedValue<Class<T>> allowedClass, ValueData data) throws InvalidValueException;
}

接口AllowedValue只是一个“标记包装器”接口,使用泛型来定义要由我的工厂创建的Class实例“允许”。

getAllowedValue是一种方法,用于使用实现此接口的具体类的内部枚举从我的允许的类“列表”中获取包装的允许的Class实例(将出现一个具体类的示例)。

create方法旨在最终创建allowedClass参数中给定的我的允许的Class实例的实例。

这是实现此接口的具体类的示例:

public class BasicValueSystem implements ValuesSystem {

    public BasicValueSystem() {
        super();
        allowedValues = (Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>) getAllowedValues();
    }

    public static enum VALUES_ID {
        MODIFIER
    }

    private static Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowedValues;

    private class BasicAllowedValue<T extends Class<? extends SystemValue>>
            implements AllowedValue<Class<? extends SystemValue>> {

    }

    @Override
    public <T extends SystemValue> T create(
            AllowedValue<Class<T>> allowedClass, ValueData data)
                throws InvalidValueException {
        if (!(allowedClass instanceof BasicAllowedValue)) {
            throw new InvalidValueException();
        }
        return null;
    }

    @Override
    public AllowedValue<Class<? extends SystemValue>> getAllowedValue(Enum<?> id) {
        return allowedValues.get(id);
    }

    @Override
    public Map<? extends Enum<?>, AllowedValue<Class<? extends SystemValue>>> getAllowedValues() {
        Map<VALUES_ID, AllowedValue<Class<? extends SystemValue>>> allowed = new EnumMap<VALUES_ID, AllowedValue<Class<? extends SystemValue>>>(VALUES_ID.class);
        allowed.put(VALUES_ID.MODIFIER, new BasicAllowedValue<Class<ModifierValue>>());
        return allowed;
    }
}

目前,create方法返回null,但是问题出在其他地方,这不是我的问题的重点

当我尝试使用以下代码创建我的“允许”值实例之一的实例时,就会发生问题:

BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<Class<? extends SystemValue>> allowed = bvs
    .getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());

编译器告诉我:

The method create(ValuesSystem.AllowedValue<Class<T>>, ValueData) in the type BasicValueSystem is not applicable for the arguments (ValuesSystem.AllowedValue<Class<? extends SystemValue>>, ModifierValueData)

我想我错过了一些有关泛型进行类型推断的东西。

谁能向我解释create方法签名在这种情况下不适用,以及如何解决?

在此先感谢您抽出宝贵的时间。

霍尔格

请注意,public interface AllowedValue<T extends Class<? extends SystemValue>>这没有多大意义。唯一有效的类型TClass<? extends SystemValue>作为类Class是终局的,不能有子类。因此,您可以在interface AllowedValue<Class<? extends SystemValue>>不做任何语义更改的情况下将其替换为,但真正的含义(imho)是interface AllowedValue<T extends SystemValue>不要Class在类型签名中乱七八糟该接口可能仍有引用的方法Class<T>

public interface ValuesSystem {

  public interface AllowedValue<T extends SystemValue>{};

  AllowedValue<? extends SystemValue> getAllowedValue(Enum<?> id);

  public <T extends SystemValue> T create
                     (AllowedValue<T> allowedClass, ValueData data);
}

相应地适应实施,BasicAllowedValue成为

private class BasicAllowedValue<T extends SystemValue> implements AllowedValue<T>

这样,您使用代码的问题就消失了。

BasicValueSystem bvs = new BasicValueSystem();
AllowedValue<? extends SystemValue> allowed = bvs
    .getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());

将编译。


注意,如果AllowedValue仅保留标记接口而不使用方法,则没有必要,Class<T>已经扮演了这个角色。当这样做时,它也将起作用:

public interface ValuesSystem {
  Class<? extends SystemValue> getAllowedValue(Enum<?> id);
  public <T extends SystemValue> T create(Class<T> allowedClass, ValueData data);
}

BasicValueSystem bvs = new BasicValueSystem();
Class<? extends SystemValue> allowed = bvs
    .getAllowedValue(BasicValueSystem.VALUES_ID.MODIFIER);
bvs.create(allowed, new ModifierValueData());

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章