Java 来自同一实例的泛型捕获不能推断为相等

Java 来自同一实例的泛型捕获不能推断为相等,java,generics,jackson,Java,Generics,Jackson,我有以下情况: public interface BaseConfig { } public abstract class BaseWidget<C extends BaseConfig> { public abstract C getConfig(); public abstract void setConfig(C config); public abstract Class<C> getConfigClass(); } public cl

我有以下情况:

public interface BaseConfig {
}

public abstract class BaseWidget<C extends BaseConfig> {
    public abstract C getConfig();
    public abstract void setConfig(C config);
    public abstract Class<C> getConfigClass();
}

public class ConcreteConfig implements BaseConfig {
    public String foo = "bar";
}

public class ConcreteWidget extends BaseWidget<ConcreteConfig> {
    private ConcreteConfig config;

    public ConcreteWidget(ConcreteConfig config) {
        this.config = config;
    }

    @Override
    public ConcreteConfig getConfig() {
        return config;
    }

    @Override
    public void setConfig(ConcreteConfig config) {
        this.config = config;
    }

    @Override
    public Class<ConcreteConfig> getConfigClass() {
        return ConcreteConfig.class;
    }
}

现在,如果我尝试将上述代码设置为通用代码(消除
ConcreteConfig
的出现,那么第一行的类型为
BaseWidget,另一个解决方法如下:

final BaseWidget<ConcreteConfig> instance = new ConcreteWidget(new ConcreteConfig());
final BaseWidget instance=new-ConcreteWidget(new-ConcreteConfig());

为了让编译器相信这两种类型
C
是相同的,我需要为上述操作引入一个类型名。在我的例子中,将代码提取到这样一个方法中的技巧如下:

private static <C extends BaseConfig> void parseSetConfig(BaseWidget<C> instance, String configJson) throws IOException {
    final C config = om.readValue(configJson, instance.getConfigClass());
    instance.setConfig(config);
}
private static void parseSetConfig(BaseWidget实例,字符串configJson)抛出IOException{
final C config=om.readValue(configJson,instance.getConfigClass());
setConfig(config);
}

这个方法可以用通配符'ed
basewidget调用,这正是我作为我想要避免的示例发布的方法。它不能严格耦合到
BaseConfig
的特定实现。编译器报告的错误确实很有帮助。它可以防止不安全的操作(从技术上讲,您可以调用
instance.setConfig(instanceofanCompatiblesubclassofBaseConfig)
。如果
ConcreteWidget
不能采用不同类型的配置(而不是
ConcreteConfig
),那么您唯一的选择就是使用
BaseWidget
…或使用原始类型。。。
@Override
public void readConfig(ObjectMapper mapper, String rawConfig) throws IOException {
    this.config = mapper.readValue(rawConfig, ConcreteConfig.class);
}
final BaseWidget<ConcreteConfig> instance = new ConcreteWidget(new ConcreteConfig());
private static <C extends BaseConfig> void parseSetConfig(BaseWidget<C> instance, String configJson) throws IOException {
    final C config = om.readValue(configJson, instance.getConfigClass());
    instance.setConfig(config);
}
final BaseWidget<? extends BaseConfig> instance = new ConcreteWidget(new ConcreteConfig());
final BaseConfig config = instance.getConfig();
final String configJson = om.writeValueAsString(config);

parseSetConfig(instance, configJson);