【问题标题】:Incompatibility using Java Generics, Interfaces and Inheritance使用 Java 泛型、接口和继承的不兼容性
【发布时间】:2013-07-03 23:06:12
【问题描述】:

我的代码存在严重问题;我正在使用实现此类接口的泛型、接口和类;总结一下:

ConfigurationListener.java

public interface ConfigurationListener<T extends Configuration> {
    public void configurationChange(ConfigurationProperty<?> [] changes, T configuration);
}

Configuration.java

public class Configuration {
    ...
    protected HashSet<ConfigurationListener<? super Configuration>> listeners;
    ...
    public void applyTo(ConfigurationListener<? super Configuration> listener) {
        if (listeners.add(listener)) {
            ...
        }
    }
    ...
}

XMLConfiguration.java

public class XMLConfiguration extends Configuration {
    ...
    @Override
    public void applyTo(ConfigurationListener<? super Configuration> listener) {
        tryLoad(); // Try to load the content of the XML file
        super.applyTo(listener);
    }
    ...
}

我在测试的时候发现如下问题,实在不明白为什么:

t3b.java

public class t3b {
    public static class Human implements ConfigurationListener<XMLConfiguration> {
        @Override
        public void configurationChange(ConfigurationProperty<?>[] changes, XMLConfiguration configuration) {
            ...
        }
    }
    public static void main(String [] args) {
        XMLConfiguration conf = new XMLConfiguration("xmlconf.xml", "sectn", new ConfigurationProperty<?> [] {
            new ConfigurationProperty<Integer>("age", 23),
            new ConfigurationProperty<String>("name", "Juan")
        });
        conf.applyTo(new Human());
    }
}

线

conf.applyTo(new Human());

打破这一切; Eclipse SDK 给我以下错误:

方法 applyTo(ConfigurationListener) 在 XMLConfiguration 类型不适用于参数 (t3b.人类)

但是 t3b.Human 使用 Configuration 的子级实现 ConfigurationListener!这就是我不明白的。

我知道我的代码逻辑可能更简单,但我想知道它为什么会失败。

我认为发布 ConfigurationProperty.java 的代码一点也不重要,但如果有帮助,请告诉我,我会发布。

谢谢!

【问题讨论】:

  • 你使用的是? super Configuration,而不是? extends Configuration
  • 我也有一种模糊的预感,这种设计不健全/类型安全。
  • 不,确实不是。你不能有一个不接受Configuration 的每个子类型的ConfigurationListener,因为listeners 可以存储任何子类型的侦听器。因此,当它触发 configurationChange() 时,无法判断哪个侦听器可以接受该更改。
  • 但是在这种情况下 super 和 extends 有什么区别?
  • 为什么会“更严格”? ? super Configuration 表示“任何属于Configuration超类型 的类型”。意思是“不是属于Configuration子类型的类型”。此外,正如我所说,我怀疑杂耍关键字在这里会有所帮助,你的整个设计都是有问题的。为什么XMLConfiguration 接受每个 类型的Configuration 的侦听器,而不仅仅是XMLConfiguration? (“配置”与“侦听器集合”是同一件事并没有帮助。这使得谈论不同的问题变得困难。)

标签: java generics inheritance interface


【解决方案1】:

问题是您的方法需要ConfigurationListener&lt;? super Configuration&gt;(任何属于Configuration 的超类型,或Configuration 本身的类型)和ConfigurationListener 需要T extends Configuration(任何属于@ 子类型的类型987654326@,或Configuration 本身)。满足这两个条件的唯一TConfiguration,但Human implements ConfigurationListener&lt;XMLConfiguration&gt;,因此不合格。

【讨论】:

  • 我改变了它,但它现在给了我另一个错误;每当我尝试调用configurationChange 时,它都会说参数类型不兼容。
  • 我想我已经知道为什么了;它不知道我是否发送了Configuration 的正确子代。我必须改变设计。
猜你喜欢
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多