簡體   English   中英

Java編譯器如何處理類型之外的缺失類型參數 <E> ,例如 <E extends Foo>

[英]How does the java compiler treat missing type arguments for types besides <E>, e.g., <E extends Foo>

我了解這三行代碼之間的區別,

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以及extendssuper之間的區別

讓我們通過在Foo中添加一個方法來進行測試:

class Foo<T extends Bar> {
    void add(T object) {

    }
}

現在讓我們嘗試兩種情況:

Foo genericFoo = new Foo();
genericFoo.add(new Bar());
genericFoo.add(new Object());

線程“主”中的異常java.lang.RuntimeException:無法編譯的源代碼-錯誤的符號類型:stackoverflow.Generics.Foo.add

因此,它會檢查以確保通用對象至少為Bar類型。


本質上,這兩個語句是相同的:

Foo<? extends Bar> genericFoo = new Foo<? extends Bar>();
Foo genericFoo = new Foo();

前者的優點是它使您必須添加Bar類型對象變得更加清晰。

最好的編寫方式可能是這樣的:

Foo<Bar> genericFoo = new Foo<>();

您仍然可以在此處添加Bar ,很明顯,泛型類型必須是Bar

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM