通配符1通配符的作用Object[]objs=newString[10];objs[0]=newInteger(100);上面代码编译是可以通过的,但在运行时会出现ArrayStoreException。因为objs数组真实的身份是String[],向String[]数组中存放Integer对象当然是不行的。ArrayListObjectlist=newArrayListString();list.add(newInteger(100);上面代码在第一行位置编译失败,因为泛型根本就不让把ArrayListString赋值给ArrayListObject,对于ArrayListObject而言,只能赋值ArrayListObject,其他的什么都不能赋值。这也说明一个问题:publicstaticvoidprintList(ListObjectlist){…}调用printList()方法只能传递给它ListObject类型的参数,而不能传递ListString,或者ListInteger,这说明我们的printList()方法有很多的限制,不够通用!!!你可能会想我再重载几次printList()方法吧,但这是行不通的!publicstaticvoidprintList(ListObjectlist){…}publicstaticvoidprintList(ListStringlist){…}因为JVM不知道什么是泛型,这两个方法在到了JVM那里时都是会把泛型参数擦除,这两个方法就是相同的方法了,擦除之后即:publicstaticvoidprintList(Listlist){…}publicstaticvoidprintList(Listlist){…}当然JVM不可能看到这样的代码,因为编译器不能让你编译通过!处理这个问题需要使用通配符!2子类型通配符publicstaticvoidprintList(List?extendsPersonlist){…}这回可以传递给printList()方法ListStudent,以及ListTeacher参数了。只要类型参数为Person,或者是Person子类型就都可以。你可以这样来理解通配符,通配符表示“不知道”的意思。即一个问号!但子类型通配符还是知道一些信息的,它只知道用户转递的类型参数一定是Person的子类型。虽然使用了通配符之后printList()方法更加通用了,但是这也是要付出一些代价的。因为不知道List中类型参数的真实类型,所以就不能调用list的add()方法了。你可能会想add(newStudent())应该是可以的,但如果List是ListTeacher呢,你怎么向这样的List添加Student呢?再想一想,add()方法已经作废了,什么都传递不了。3父类型通配符publicstaticvoidprintList(List?superStudentlist){…}可以传递给printList()方法ListStudent,以及ListPerson,甚至ListObject也是可以的。只要传递给printList()方法的List类型参数为Student,或者Student的父类型就是可以的。你现在可以向list中添加Student类型的参数,例如:list.add(newStudent())。因为用户提供的参数ListStudent、ListPerson、ListObject,无论哪一种类型,对于list.add(newStudent())都是合法的。但是,现在我们不知道list的get()方法返回的是什么了!因为用户传递的可能是ListStudent、ListPerson、ListObject,如果我们用Students=list.get(0),那么如果list其实是一个ListPerson岂不是出错了!没错,只能使用Object来接收list.get(0)的返回值了。4无界通配符所谓无界通配符,即List?,对通配符没有限定。你可以给List?赋任意的值,但是,你能使用这样的list干什么呢?也不能add(),也只能使用Object来接收get()方法返回值。所以,通常List?只能表示你在使用泛型而已!编译器会认为List?比List更加优雅一些!你可能也看出来了,泛型还真是很垃圾!!!这也是没有办法中的办法,现在的泛型是迁移性兼容的一种版本而已!Java设计者不敢让JVM知道泛型的存在,原因是为了兼容1.4之前的版本。当所有人都在使用1.5以上版本的JDK后,Java的泛型可能就不会再是编译期状态了。