简体   繁体   English

java泛型协方差

[英]java generics covariance

I am having trouble understanding the following article: http://www.ibm.com/developerworks/java/library/j-jtp01255.html 我无法理解以下文章: http//www.ibm.com/developerworks/java/library/j-jtp01255.html

Under, 下,

Generics are not covariant 泛型不是协变的

the author states, 作者说,

Because ln is a List, adding a Float to it seems perfectly legal. 因为ln是一个List,所以添加一个Float似乎是完全合法的。 But if ln were aliased with li, then it would break the type-safety promise implicit in the definition of li -- that it is a list of integers, which is why generic types cannot be covariant. 但是如果ln与li混淆,那么它将破坏li定义中隐含的类型安全承诺 - 它是一个整数列表,这就是泛型类型不能协变的原因。

I can't understand the part where it says "if ln were aliased with li". 我无法理解它所说的“如果ln与li混淆”的部分。 What does the author means by alias?(reference?). 作者对别名的含义是什么?(参考?)。 The code snippet above the quoted line seems to illustrate WHAT is illegal in java and not WHY. 引用行上方的代码片段似乎说明了什么在java中是非法的而不是为什么。 It would be very helpful to me if somebody could explain with an example. 如果有人能用一个例子来解释,对我来说会很有帮助。 Thanks in advance. 提前致谢。

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

In Java, Integer inherits from Number (java.lang.Number) , so intuitively, anything that is an Integer (java.lang.Integer) is also a number, but what that article points out is that with generics it does not work that way, because considering that example, you could end up putting a float (which is a Number) into a List<Integer> , which is illegal because a float is not an integer. 在Java中,Integer继承自Number (java.lang.Number) ,因此直观地说,任何Integer (java.lang.Integer)都是一个数字,但是文章指出的是泛型它不起作用因为考虑到这个例子,你可能最终将一个float(这是一个Number)放入List<Integer> ,这是非法的,因为float不是一个整数。

Conclusion: Generics are not covariant. 结论:泛型不是协变的。

Note: I recommend you read Effective Java (2nd Edition) Chapter 5: Generics. 注意:我建议您阅读Effective Java(第2版)第5章:泛型。

If you could do something like this: 如果你能做这样的事情:

List<Float> foo;
List<Object> bar;

foo = new ArrayList<Float>();
bar = foo;

foo.add(1.0f);
bar.add("Hello");

things would go VERY wrong. 事情会非常错误。 In this example bar is an alias for foo, and if you could do it you would lose the type safety that are the main reason that generics exist. 在这个例子中,bar是foo的别名,如果你能做到这一点,你将失去类型安全性,这是泛型存在的主要原因。

public class vechicle {
void drive(){
}
}
class car extends vechicle{
        //Covariance
    vechicle getObject(){
        return new car();
    }
        //contravariance
    car getmyObject(){
        return (car) new vechicle(); 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM