簡體   English   中英

為什么推斷泛型類型在這里不起作用?

[英]Why does inferring of generic type does not work here?

假設我有以下類:

interface MyS<T extends MyT<S, T>, S extends MyS<T, S>> {
}
interface MyT<S extends MyS<T, S>, T extends MyT<S, T>> {
}
public class MySImpl implements MyS<MyTImpl, MySImpl> {
}
public class MyTImpl implements MyT<MySImpl, MyTImpl> {
}

我可以構建以下測試用例,它可以在沒有任何警告的情況下成功編譯和運行:

public class STTest {

  @Test
  public void test() throws Exception {
    createInstance(MyTImpl.class);
  }

  public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
      final Class<? extends MyT<S, T>> beanClass) throws Exception {

    final MyT<S, T> bean = beanClass.newInstance();
  }
}

好的。 但我希望這會產生相同的效果:

public class STTest {

  @Test
  public void test() throws Exception {
    createInstance(MyTImpl.class);
  }

  public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
      final Class<T> beanClass) throws Exception {

    final T bean = beanClass.newInstance();
  }
}

但是,這是一個編譯錯誤:

S的無效推斷類型; 推斷類型不符合推斷的聲明邊界:MySImpl bound(s):MyS

為什么是這樣?

更新:

我注意到該行為依賴於編譯器。 我使用OpenJDK 1.6編譯器(javac 1.6.0_27)來編譯代碼。 它打破了。 然而:

  • OpenJDK 1.7編譯器(javac 1.7.0_21)和
  • Oracle 1.6編譯器(javac 1.6.0_37)

在第二個例子中都可以正常工作。

但是:這是OpenJDK 1.6編譯器中的錯誤還是Java語言規范中的歧義?

參數類型在第二個示例中沒有以任何方式提及S. 編譯器告訴你它因此無法推斷它。

詳細說明。 在第一個例子中,你要求一個Class<? extends MyT<S, T>> Class<? extends MyT<S, T>> test() ,你給它一個Class<MyTImpl> 當編譯器檢查邊界時,它將MyT<S, T>MyTImpl匹配MyT<S, T>並發現MyTImpl實現MyT<MySImpl, MyTImpl> ,因此它可以通過簡單地將這兩個東西放在一起來推斷出MySImplSMyTImpl for T

然后它檢查STMySImplMyTImpl ,然后成功。

在第二個示例中,您要求Class<T> 編譯器看到Class<MyTImpl> ,推斷MyTImpl T MyTImpl ,並且完成了。 如果沒有推斷出S ,就會出錯。

T約束檢查可以提供S的信息,但不會發生。

暫無
暫無

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

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