类比学习——java 泛型& kotlin 泛型 in out where_knight

学习 kotlin 泛型的时候,经常会遇到 in out 这两个词,一会用in 一会用out,为啥这里要用 out ?为啥哪里用 in ?啥什么用 out 啥时候用in ?对应上面问题以前我是晕乎乎的,不是很明白,于是打算写这篇文章梳理一下,搞清楚怎么回事。

Java 泛型

在学kotlin 泛型之前,先回顾一下Java中的泛型 为了方便说明引入下面几个类 类比学习——java 泛型& kotlin 泛型 in out where_knight

具体代码

publicclassAnimal{}publicclassDogextendsAnimal{}publicclassCatextendsAnimal{}publicclassCorgiextendsDog{}publicclassResult{private T data;publicResult(){}publicResult(T data){this.data = data;}publicvoidsetData(T data){this.data = data;}public T getData(){return data;}}

1.不可型变

Result dogResult =newResult();
Result animalResult = dogResult;

虽然 Dog 是 Animal 的子类,但是Java 泛型是不可以型变的,Result 对象不能赋值给 Result , 他们之间没有关系。 如果 Java 泛型不是这样设计的就容易造成运行时异常,例如

 Result dogResult =newResult();
 Result animalResult = dogResult;
 animalResult.setData(newAnimal());
 Dog dog = dogResult.getData();

所以 Java 这样设计是为了安全考虑。 为了安全,这样的限制显然会失去一些API的灵活性。于是 Java 提供有限制通配符 ? extends X 、? super X 、 来提升API 的灵活性。

2.型变性通配符 —— ? extends

Result dogResult =newResult(newDog());
Result animalResult = dogResult;
 Animal animal = animalResult.getData();