一:通配泛型有三类:<?>非受限通配、<? extends T>受限通配 、<? super T>下限通配
案例一:
package fanxin; public class WildCardNeedDemo { public static void main(String[] args) { GenericStack<Integer> inStack = new GenericStack<>(); inStack.push(1); inStack.push(2); inStack.push(3); System.out.println("the max number is:"+max(inStack));//编译期出错 } public static double max(GenericStack<Number> stack) { double max_ = stack.pop().doubleValue(); while(!stack.isEmpty()) { double value = stack.pop().doubleValue(); if(value > max_) { max_ = value; } } return max_; } } /** * 程序在编译期间错误,因为inStack不是GenericStack<Number>的实例,尽管Integer是Number的子类型, * 但是GenericStack<Integer>不是GenericStack<Number>的子类型, * 为解决这个问题,提出了通配泛型类型 * 有三种形式:?(非受限通配) 、<? extends T>(受限通配) 、<? super T>(下限通配),其中?相当于<? extends Object> * */
用通配泛型解决问题:
案例二:
package fanxin; public class AnyWildCardDemo { public static void main(String[] args) { GenericStack<Integer> inStack = new GenericStack<>(); inStack.push(1); inStack.push(2); inStack.push(3); print(inStack); } public static void print(GenericStack<? extends Number> stack) { while(!stack.isEmpty()) { System.out.print(stack.pop() + " "); } } }
案例三:下限通配:
package fanxin; public class SuperWildCardDemo { public static void main(String[] args) { GenericStack<String> stack1 = new GenericStack<>(); GenericStack<Object> stack2 = new GenericStack<>(); stack2.push("java"); stack2.push(1); stack1.push("oracle"); add(stack1, stack2); print(stack2); } public static <T> void add(GenericStack<T> stack1,GenericStack<? super T>stack2) { while(!stack1.isEmpty()) { stack2.push(stack1.pop()); } } public static void print(GenericStack<?> stack) { while(!stack.isEmpty()) { System.out.print(stack.pop() + " "); } } } /** * * <? super T>表示 T或者T的父类型 * 15行也可以改成 public static <T> void add(GenericStack<? extends T> stack1,GenericStack<T>stack2) * * */
-----------------------------------------------------------
二、消除泛型和对泛型的限制:
泛型消除是在编译期间将泛型消除,避免了在JVM中出现类型泛滥的现象。
泛型的限制:
1】不能使用new E():泛型运行时不可用
2】不能使用new E[]
3】在静态上下文中不允许类的参数是泛型类型
package fanxin; public class Test<E> { public static void m(E o1) { //非法 } public static E o1; //非法 static { E o2; //非法 } } /** * 在静态上下文中不允许类的参数是泛型类型 * 由于泛型类的所有实例都有相同的运行时类,所以泛型类的静态变量和方法是被它的所有实例所共享的 * (也就是说,作为一个类中的静态部分,只有在类第一次实例化的时候执行一次, * 那么在进行类的泛型实例化的时候,不管传递什么参数,对静态块的部分不会有任何影响,从而产生错误) * */4】异常类型不能是泛型:try子句抛出的异常要和catch中的异常匹配,而运行时泛型信息不可得