簡體   English   中英

Java泛型-帶有可選包裝泛型的意外情況

[英]Java generics - unexpected situation with Optional wrapping generics

我已經遇到以下情況:

import com.google.common.base.Optional;

public class CovarianceTest {

    class Race {
    }

    class Dog<Race> {
    }

    public Optional<Dog<? extends Race>> getDog() {
        Dog<? extends Race> dogWithSomeRace = new Dog();
        return Optional.of(dogWithSomeRace);
    }
}

這樣的情況會導致編譯問題。 IDE說:

Incompatible types.
Required: Optional<Dog<? extends Race>>
Found: Optional<? extends Dog<? extends Race>

這顯然是錯誤的。

有人可以解釋為什么會這樣嗎?

似乎您將類的泛型類型聲明與泛型類型參數的邊界聲明混淆了。

在您的情況下:

class Race {}

class Dog<Race> {} // "Race" is declared as a generic type in dog. It's not referring to your Race class in any way.

您對Dog定義等同於

class Dog<E> {}

如果要將Race的子類設置為Dog的通用邊界,請執行例如

class Dog<E extends Race> {}

您還可以優化方法的泛型聲明:

public Optional<Dog<? extends Race>> // this could be shortend to Dog<?>, because Dog's boundary is already limited to Race in the class signature
                                     getDog() {
    Dog<? extends Race> dogWithSomeRace // This can be shortend aswell to Dog<?> 
                                        = new Dog(); // Missing type declaration in the constructor call 
    return Optional.of(dogWithSomeRace);
}

這是您的代碼:

  1. 編譯器認為Race (在Dog<Race>類中)是一個類型參數,將用於進一步對class Dog進行參數化。
  2. 在作業Dog<? extends Race> dogWithSomeRace = new Dog(); Dog<? extends Race> dogWithSomeRace = new Dog(); 這被認為不是最佳實踐。

在此處輸入圖片說明

我相信下面的代碼就是您要嘗試執行的操作。 使用T作為類型參數。 開始了:

import com.google.common.base.Optional;

public class CovarianceTest {

    class Race {
    }

    class Dog<T> {
        void whatever(T t) {
            System.out.println(t);
        }
    }

    public Optional<Dog<? extends Race>> getDog() {
        Dog<? extends Race> dogWithSomeRace = new Dog<Race>();
        return Optional.of(dogWithSomeRace);
    }

    public static void main(String[] args) {
        System.out.println((new CovarianceTest()).getDog().isPresent());
        System.out.println((new CovarianceTest()).getDog().get().getClass());
    }
}

打印效果很好:

真正
類CovarianceTest $ Dog

暫無
暫無

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

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