java - 覆盖下限参数

标签 java generics overriding

我想知道为什么 java 不允许覆盖下限泛型参数。

public interface NumberConsumer {
    public void accept(Consumer<? super Number> consumer);
}

public interface IntegerConsumer extends NumberConsumer {
    @Override
    public void accept(Consumer<? super Integer> consumer);
}

在上面的示例中,覆盖方法 accept 是完全安全的,因为 NumberConsumer 可以接受数字、可序列化对象和对象的消费者,而 IntegerConsumer 可以接受所有这些和整数。

这也是不允许的,尽管也是绝对安全的。

public interface IntegerPrinter {
    public void print(List<? extends Integer> list);
}

public interface NumberPrinter extends IntegerPrinter {
    @Override
    public void print(List<? extends Number> list);
}

这里NumberPrinter可以取List<? extends Integer>没有任何问题。

最后,返回时允许一些类似(或相反)的情况。

public interface NumberListProducer {
    java.util.List<? extends Number> next();
}

public interface IntegerListProducer extends NumberListProducer {
    @Override
    java.util.List<? extends Integer> next();
}

最佳答案

这不是泛型问题,而是 java 如何处理它的 overriding功能。

覆盖方法与它覆盖的方法具有相同的名称、参数数量和类型以及返回类型。覆盖方法还可以返回被覆盖方法返回的类型的子类型。此子类型称为协变返回类型。

因此,仅在返回类型中重写方法时才允许类型继承。类型的精确匹配应该发生在方法参数中。

例如,以下情况抛出错误。

  1. interface PaterntInterface {
        public void accept(Integer consumer);
    }
    
    interface ChildInterface extends NumberConsumer {
        @Override
        public void accept(Number consumer);
    }
    
  2. interface PaterntInterface {
        public void accept(Number consumer);
    }
    
    interface ChildInterface extends NumberConsumer {
        @Override
        public void accept(Integer consumer);
    }
    

    以下情况可以正确编译。

  3. interface PaterntInterface {
        public void accept(Integer consumer);
    }
    
    interface ChildInterface extends NumberConsumer {
        @Override
        public void accept(Integer consumer);
    }
    
  4. interface PaterntInterface {
        public void accept(Number consumer);
    }
    
    interface ChildInterface extends NumberConsumer {
        @Override
        public void accept(Number consumer);
    }
    

你的论点是你的第一个案例,

public interface NumberConsumer {
    public void accept(Consumer<? super Number> consumer);
}

public interface IntegerConsumer extends NumberConsumer {
    @Override
    public void accept(Consumer<? super Integer> consumer);
}

应该没问题因为Consumer<? super Integer>Consumer<? super Number> 的父类(super class)无效,因为覆盖需要方法参数类型的精确匹配。你的第二个案例也一样。 第三种情况编译因为java.util.List<? extends Integer>java.util.List<? extends Number> 的子类型, 并且在方法覆盖中允许返回类型的继承

关于java - 覆盖下限参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49055005/

相关文章:

java - 在html中使用spring标签

java - Struts2 jQuery 插件 : trigger link on double click

java - 通过传递泛型方法进行重构

python - Django : DiscoverRunner overriding raise error

java - 类型级别的 Spring Security @PreAuthorize 不能在方法级别上覆盖

c# - 是否可以在引入其他泛型类型的泛型类上使用构造函数?

generics - 一种处理嵌入一个通用结构的所有结构类型的方法(json 编码)

arrays - 如何在 typescript 中扩展和覆盖数组方法

Magento:将选项卡添加到管理员订单详细信息页面

java - Netbeans:JButton 按钮无法设置可见