java - java 编译器如何处理 <E> 之外类型的缺失类型参数,例如 <E extends Foo>

标签 java generics

我明白这3行代码之间的区别,

ArrayList list1 = new ArrayList();
ArrayList<Object> list2 = new ArrayList<Object>();
ArrayList<? extends Object> list3 = new ArrayList<? extends Object>();

但假设我有这个示例类 Foo,

class Foo<T extends Bar> {
    // ...
}

编译器如何以不同的方式处理这些(如果有的话)?

Foo foo1 = new Foo();
Foo<? extends Bar> foo2 = new Foo<? extends Bar>();

我看到很多例子说当类型参数被排除时它不会检查,但这些例子通常适用于 List可以放入任何内容的示例等( public interface List<E> extends Collection<E> )。 当省略声明时,编译器是否默认使用声明中限制最少的类型参数,或者只是允许任何内容?此外,如果它确实默认声明,那么就是有任何理由使用 foo1 中的样式超过foo2

编辑:我的问题有所不同,因为它询问编译器如何处理特定示例以及它们有何不同,引用的问题是关于 PECS 以及 extends 之间的区别和super

最佳答案

TL;DR

它们是相同的。

长格式

这是一个简单的测试用例。在 Eclipse 中,两个 put 调用均出现错误。说明该方法不适用于参数。

public class Main {

   public static void main(final String[] args) {

      final Test test1 = new Test();
      final Test<? extends String> test2 = new Test<? extends String>();

      test1.put(new Integer(1));
      test2.put(new Integer(1));
   }

   private static class Test<T extends String> {

      public void put(final T value) { }

   }
}

当其中一个被注释掉并且单独编译时,编译器会给出相同的错误。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
  The method put(String) in the type Main.Test is not applicable for the arguments (Integer)
  The method put(capture#1-of ? extends String) in the type Main.Test<capture#1-of ? extends String> is not applicable for the arguments (Integer)

  at Main.main(Main.java:9)

关于java - java 编译器如何处理 <E> 之外类型的缺失类型参数,例如 <E extends Foo>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29754372/

相关文章:

generics - 通用静态方法调用无法在 Java 8 中编译

c# - 实现通用接口(interface)

java - 泛型扩展行类型

c# - 无法将类型 System.Collections.Generic.IEnumerable<T> 隐式转换为 System.Collections.Generic.List<B>

java - GWT:为什么 "setAnimationEnabled(true);"不考虑对话框大小?

java - 如何在tomcat中设置Oracle时区区域

java - 如何将 XML(字符串)附加到已创建文档开头的 XmlEventWriter (StAX)

java - 保存实例以避免在选项卡之间切换时丢失数据

scala - 如何避免 Scala 中类型绑定(bind)的重复

java - 正则表达式在Java中替换部分字符串