通用问题:T扩展了接口类型。无法调用方法返回扩展类型的对象?

时间:2016-09-13 16:28:37

标签: java generics

我在父类中声明了这个方法:

protected <ConfigT extends LoadableConfig> ConfigT getConfig(final String configId) {
    return (ConfigT)getConfigService().getConfig(configId, getDriver());
}

配置服务方法定义如下:

@SuppressWarnings("unchecked")
@Override
public <ConfigT extends LoadableConfig> ConfigT getConfig(String configId, WebDriver driver) {

    //noinspection unchecked
    Map<String,LoadableConfig> profile = profiles.get(getProfileName(driver));

    if(profile != null) {
        return (ConfigT) profile.get(configId);
    }

    return null;
}

我想要的配置类型在这里:

public interface AccessibleConfig extends LoadableConfig, PolleableConfig {
 ....
}

这行代码抛出了一个不兼容的类型错误:

 AccessibleConfig config = getConfig(ValidationPane.class.getCanonicalName());

这怎么可能? AccessibleConfig扩展LoadableConfig。调用的方法声明返回类型是扩展LoadableConfig的某种类型。我正在运行jdk1.8.0_102.jdk。这种故障发生在IntelliJ以及从命令行使用Maven进行编译时。我可以使用扩展LoadableConfig类型的其他配置类型来执行此操作。

编辑:

家长班:

public abstract class AbstractLoadable<T extends AbstractLoadable<T>> {

    private Map<String,LoadableConfig> profiles = new HashMap<>();

    protected <T extends LoadableConfig> T getConfig(final String configId) {
        return (T) profiles.get(configId);
    }
}

具体类:

public class ConcreteLoadable extends AbstractLoadable {

    public ConcreteLoadable(final String profileName) {

        AccessibleConfig config = getConfig(ConcreteLoadable.class.getCanonicalName());
    }

}

接口类型:

public interface LoadableConfig {
    Integer getLoadTimeoutInSeconds();
    void setLoadTimeoutInSeconds(final Integer loadTimeoutInSeconds);
}

public interface AccessibleConfig extends LoadableConfig {
    Boolean getHoverOverAccessorWithJavascript();
    void setHoverOverAccessorWithJavascript(final Boolean hoverOverAccessorWithJavascript);
    Boolean getClickAccessorWithJavascript();
    void setClickAccessorWithJavascript(final Boolean clickAccessorWithJavascript);
}

因此,生成这个最小示例的练习实际上很容易识别编译器错误的来源。我在下面发布了这个问题的答案。我谦卑地接受我实际上并没有发布一个完整的例子。

1 个答案:

答案 0 :(得分:1)

我已经确定了问题所在。具体类需要将自身传递给父类,因为父类是反身通用的。错误消息并不是非常有用,所以我想到了父类方法的泛型参数而不是应用于父类本身的泛型参数。

ConcreteLoadable的类声明需要更改为此以消除编译错误:

public class ConcreteLoadable extends AbstractLoadable<ConcreteLoadable> {

    public ConcreteLoadable(final String profileName) {

        AccessibleConfig config = getConfig(ConcreteLoadable.class.getCanonicalName());
    }

}