java - 泛型 super 与扩展

标签 java generics scjp generic-type-argument

就在我以为我终于理解了泛型的时候,我看到了下面的例子:

public class Organic<E> {
          void react(E e) { }
          static void main(String[] args) {
            //1: Organic<? extends Organic> compound = new Aliphatic<Organic>(); 
            //2: Organic<? super Aliphatic> compound = new Aliphatic<Organic>(); 
           compound.react(new Organic());
           compound.react(new Aliphatic());
           compound.react(new Hexane());
 } }
 class Aliphatic<F> extends Organic<F> { }
 class Hexane<G> extends Aliphatic<G> { }

它说,如果第 1 行没有注释,下面的代码将不会编译:

  compound.react(new Organic());  
  compound.react(new Aliphatic());  
  compound.react(new Hexane());

如果第 2 行被取消注释,则以下内容将无法编译:

compound.react(new Organic());

在第二个示例中,允许使用 Aliphatic 及其父类(super class)型。那么为什么不允许脂肪族?

在第一个例子中,为什么不允许new Organic??

第一个编译器错误:

- The method react(capture#1-of ? extends Organic) in the type Organic<capture#1-of ? extends Organic> is not applicable for the arguments (Organic)
- The method react(capture#2-of ? extends Organic) in the type Organic<capture#2-of ? extends Organic> is not applicable for the arguments (Aliphatic)
- The method react(capture#3-of ? extends Organic) in the type Organic<capture#3-of ? extends Organic> is not applicable for the arguments (Hexane)

第二个编译器错误:

- The method react(capture#1-of ? super Aliphatic) in the type Organic<capture#1-of ? super Aliphatic> is not applicable for the arguments  (Organic)

最佳答案

你的第一个声明

Organic<? extends Organic> compound

表示compound 可以Organic<SomeSubtypeOfHexane> (因为 Aliphatic 扩展了 OrganicHexane 扩展了 AliphaticSomeSubtypeOfHexane 扩展了 Hexane )。

在这种情况下,compound.react(new Organic()) , compound.react(new Aliphatic())compound.react(new Hexane())会导致类型错误,因为 Ecompound必须是 SomeSubtypeOfHexane (或其子类型)。


你的第二个声明

Organic<? super Aliphatic> compound

表示compount 可以Organic<Aliphatic> .

在那种情况下compound.react(new Organic())会导致类型错误,因为 E必须是 Aliphatic (或其子类型)。


记住使用 A<? extends B> 声明变量或 A<? super B>

  • 扩展 可以分配给它的对象数量,因此,
  • 限制可以用变量做什么。

由于类的确切类型是未知的(只有一个约束 是已知的),编译器必须在安全方面犯错误并禁止某些非协变或逆变的操作。 (如果您还不熟悉,Co- and contravariance 就是这些类型的泛型的科学背景。)

关于java - 泛型 super 与扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13133714/

相关文章:

java - Jetty Http 客户端日志记录

java - 无法使用 Documentlistener 清除 jtextfield

c++ - 嵌套通用容器迭代 C++

Android:我可以在 AsyncTask 中使用通用返回类型吗 - doInBackGround

java - 使用 null 参数进行意外重载方法编译器选择

java - 覆盖 `equals()` 方法在 `HashMap` 中给出意外结果

java - 代码看不到 JTextField 的值,尽管它显示在界面中

java - 停止在 BoxLayout 中扩展 JScrollPane

c# - 为什么这种泛型场景会导致 TypeLoadException?

java - 垃圾收集 - 空引用和引用新对象