簡體   English   中英

Class 與 java generics 的層次結構問題

[英]Class hierarchy problem with java generics

我在通用 function 中遇到了 class 層次結構的問題。 我需要強制執行,使用 function 中指定的兩個類TU ,一個是另一個的孩子。 我驚訝地發現構造<T extends U>根本不強制UT的父子關系。 相反,它還允許TU是同一類型。

這會產生一個問題,因為它看起來像在U extends T的情況下 Java 不會指示錯誤,而是會很高興地推斷出兩個對象都是T類型(毫無疑問這是真的),然后編譯並運行代碼沒有任何抱怨。

這是一個說明問題的示例:

public class MyClass {
    public static void main(String args[]) {
      Foo foo = new Foo();
      Bar bar = new Bar();

      // This code is written as intended
      System.out.println( justTesting(foo, bar) );

      // This line shouldn't even compile
      System.out.println( justTesting(bar, foo) );
    }
    
    static interface IF {
       String get(); 
    }
    
    static class Foo implements IF {
       public String get(){return "foo";} 
    }
    
    static class Bar extends Foo {
        public String get(){return "bar";}
        
    }
    
    static <G extends IF , H extends G> String justTesting(G g, H h) {
        if (h instanceof G)
            return h.get() + " (" + h.getClass() + ") is instance of " + g.getClass() + ". ";
        else
            return "it is the other way round!";
    }
}

這是 output:

bar (class MyClass$Bar) is instance of class MyClass$Foo. 
foo (class MyClass$Foo) is instance of class MyClass$Bar. 

我需要確保編譯器觀察到泛型類的父子關系。 有沒有辦法做到這一點?

它可以編譯,因為IFHG“下限”。

意思是:Generics 並不像我們想象的那么“動態”,我們也可以這樣寫:

static <G extends IF, H extends IF> ... // just pointing out that G *could* differ from H 

忽略 null 檢查,這是你想要的:

  static <G extends IF, H extends G> String justTesting(G g, H h) {
    if (g.getClass().isAssignableFrom(h.getClass())) {
      return h.get() + " (" + h.getClass() + ") is instance of " + g.getClass() + ". ";
    } else {
      return "it is the other way round!";
    }
  }

?

Class.isAssignableFrom()


印刷:

bar (class com.example.test.generics.Main$Bar) is instance of class com.example.test.generics.Main$Foo. 
it is the other way round!

並注意“匿名課程”,例如:

System.out.println(
  justTesting(
    new IF() {
      @Override
      public String get() {
        return "haha";
      }
    }, foo)
);

System.out.println(
  justTesting(
    foo, new IF() {
      @Override
      public String get() {
        return "haha";
      }
    }
  )
);

打印兩個“它是相反的方式”。 所以這里的決定不是那個“二元”的。

暫無
暫無

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

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