通用方法。多个参数匹配

时间:2018-11-02 18:14:06

标签: java generics

我不知道为什么这段代码能正常工作。

static <T> int compare(T t1, T t2) {
    return 0;
}

public static void main(String[] args) {
    compare(new Thread(), new StringBuilder());
}

因为当我们遇到这样的事情时:

static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    return;
}

public static void main(String[] args) {
    fromArrayToCollection(new Thread[] {}, new ArrayList<StringBuilder>()); // error
}

我们有一个错误。 为什么在第一个示例中编译器不检查两个参数的匹配?对不起,愚蠢的问题。

2 个答案:

答案 0 :(得分:5)

泛型是不变的

泛型是不变,而不是协变

这意味着,尽管您可以执行以下操作:

if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
    SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
    return 1;
}

您不能这样做:

if imageUrl.count > 0 {
        let eachImage = imageUrl[indexPath.row]
        Alamofire.request(eachImage).responseImage(completionHandler: {(response) in
            print("answer\(response)")
            if let image = response.result.value{
                DispatchQueue.main.async {
                    cell.ImageView.image = image
                }
            }
        })
        }

因此Dog dog = new Dog(); Animal animal = dog; // Dog works for Animal, classes are covariant 的类型为List<Dog> dogs = List.of(new Dog()); List<Animal> animals = dogs; // Error, generics are invariant 不是。但是List<Dog>的类型为List<Animal>

这当然是有道理的,因为Dog将接受Animal,而animals不接受。


说明

在您的第一个代码中,您没有指定要使用的类型,例如:

Cat

因此,让编译器推断类型。它搜索dogscompare<Foo>(...) 共有的一种类型,即Thread

所以StringBuilder解析为Object,很好:

T

在第二个示例中,它不能选择Object,因为static int compare(Object t1, Object t2) { return 0; } 的行为与Object不同,因为泛型是不变的。因此无法找到匹配的类型,从而发生错误。

另请参阅Why are arrays covariant but generics are invariant?

答案 1 :(得分:2)

我想补充一点,在第二个代码段中进行简单的更改即可纠正错误:

static <T> void fromArrayToCollection(T[] a, Collection<? extends T> c) { ... }
                                                             ^

现在,Java编译器将再次推断Object

fromArrayToCollection(new Thread[]{}, new ArrayList<StringBuilder>());

此外,您可以显式添加type参数:

Main.<Object>fromArrayToCollection(new Thread[]{}, new ArrayList<StringBuilder>());
        ^

T => Object

static void fromArrayToCollection(Object[] a, Collection<? extends Object> c) { ... }

进一步阅读:Upper Bounded Wildcards