标签:function assignable Listis List 泛型 不变性 type 赋值
泛型的实际应用情况和通配符的使用,关于大范围和小范围互相赋值的时候JVM编译报错的问题:
问题描述:继承关系
class A {} class B extends A {} class C extends A {} class D extends B {}
下面给出了几种说法:
The type List<A>is assignable to List. The type List<B>is assignable to List<A>. The type List<Object>is assignable to List<?>. The type List<D>is assignable to List<?extends B>. The type List<?extends A>is assignable to List<A>. The type List<Object>is assignable to any List reference. The type List<?extends B>is assignable to List<?extends A>.
(1)首先谈泛型只是在编译期保证对象类型相同的技术,比如在指定的类中声明了一个泛型,那么表示在此类中某一个属性的类应该是声明的这种类型的,而真正在代码运行的时候JVM会查出来泛型的存在。
(2)Java数组具有协变性、集合不具备协变特性
function(Person person);
对于上面这个函数,如果我传入的是一个Student student对象的话,编译期是不会报错的,这是多态的特性。
function(Person[] person);
而对于上面的这个函数如果我传入的是一个Student[] student数组进去的话,编译期也不会报错,这是数组的协变性。
public class TestConvert { public static void main(String[] args) { Student[] students = new Student[10]; System.out.println(TestConvert.function(students)); } public static int function(Person[] persons) { return 1; } }
(3)但是如果我的函数是这样的:我想要传进去一个List<Student> students的话,编译器就会报错,这就是集合的泛型不变性,这点与数组的协变性不同。
function(List<Person> persons);
我们可以将泛型改成这样 function (List <? extends Person> ),这样之后,当我们再传入一个List <Student> students集合进去,编译器就就不会报错了。也就是说可以传入包含Person的子类的List了。也就是引进了通配符的使用。
注:<? extends A> 代表小于等于A的范围,<? super A>代表大于等于A的范围,<?>代表全部范围。
换一句话说List<A>和List<B>的集合对象不能直接来赋值的,而只有是一个范围的情况才可以被赋值进去,比如List<? extends A>这个就代表的是一个大的范围,可以将其子类的集合对象List<B>放进去。
标签:function,assignable,Listis,List,泛型,不变性,type,赋值 来源: https://www.cnblogs.com/dashenaichicha/p/11975471.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。