有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型,将一个列表复制到另一个列表

我在java中有两个函数签名,它应该将列表src复制到列表dst:

1. public static <T> void copy1(List<T> dst, List<? extends T> src)
2. public static <T> void copy2(List<? super T> dst, List<? extends T> src)

问题是这两个函数签名之间是否存在差异,以及是否存在第二个选项有效而第一个选项无效的情况


共 (1) 个答案

  1. # 1 楼答案

    回答第一个问题,这两个函数签名在java中是否不同<不!测试这一点的最快方法是同时调用它们copy,并验证编译器是否抱怨重复的方法

    public static <T> void copy(List<T> dst, List<? extends T> src)
    public static <T> void copy(List<? super T> dst, List<? extends T> src)
    

    你的第二个问题是,在什么情况下,一个有效,另一个无效

    基本上我们讨论的是第一个参数,dst,因为它是两者之间唯一的区别

    对于任何给定的T,在copy2的情况下,第一个参数必须是T或T本身的超类,第二个参数必须是T或T本身的子类。编译器的解释是,第一个参数泛型类型必须是T,第二个参数泛型类型只是T的扩展。事实上,如果您尝试,您将看到编译器将只采用与第一个参数的泛型类型相同的类型或该参数的派生类:

    public static <T> void copy2(List<? super T> dst, List<? extends T> src) {
        // Copy
    }
    
    public static void main(String[] args) {
        List<Number> dst = new ArrayList<Number>();
        List<Integer> src = getSource();
    
        copy2(dst, src);  // Works when 2nd generic param type subclass of 1st
        copy2(dst, dst);  // Works when 2nd generic param type same as 1st
        copy2(src, dst);  // Invalid types for method!
    }
    

    在copy1的情况下,第一个参数T,第二个参数仍然只是T的子类。所以我们在这里讨论相同的场景。在这种情况下,没有一种情况下一个可行,另一个不行

    public static <T> void copy1(List<T> dst, List<? extends T> src) {
        // Copy
    }
    
    public static void main(String[] args) {
        List<Number> dst = new ArrayList<Number>();
        List<Integer> src = getSource();
    
        copy1(dst, src);  // Works when 2nd generic param type subclass of 1st
        copy1(dst, dst);  // Works when 2nd generic param type same as 1st
        copy1(src, dst);  // Invalid types for method!
    }