关于java泛型的理解

泛型有泛型类,泛型方法,泛型边界的问题

泛型类的使用:

LinkStack<String> lls = new LinkStack<>();可以根据传入的类型确定泛型T的类型,比如传入String类型,lls类就只能添加String类型的了,泛型使类更加灵活具备不同的功能。注意:泛型类在创建的时候必须制定类型,不过编译的时候相关的泛型类型会被擦除,也就是运行的时候LinkStack<String> lls = new LinkStack<>();和LinkStack<Integer> lls = new LinkStack<>();是一样的

关于java泛型的理解

泛型方法:能够使用泛型方法的优先使用泛型方法,定义泛型方法,只需要将方形参数列表置于返回值之前就可以了,就像这样

public <T> void f(T x ){System.out.println(x.getClass().getName())}//体现了泛型方法使用的时候可以不下确定具体类型

多泛型方法public <A,B,C> void f(A a,B b,C c){}

泛型边界理解:边界是可以控制你使用的参数类型的上线,更重要的是你可以按照自己的边界去调用想要的方法。

因为T类型继承了HasColor,就可以使用该接口的方法

关于java泛型的理解

通配符:

虽然integer是Number的子类型,但是用Number的容器却不能存入integer的类型。实际这两个容器并不是同一类型的容器,是不同类型的List,这时候为了显示java的多态性,就需要使用通配符?如下图二,?允许你编译的时候传入任何类型的参数

关于java泛型的理解关于java泛型的理解

通配符边界:如果我们想要控制通配符的上下界,可以使用<? extend A>或者<? super A>

<? extend A>可以理解为,具有从A类型继承的类型列表,报错是因为? extend Integer只拥有继承Integet类型的

改为? extend Number就不会报错,以为Integer也是Number的子类。

关于java泛型的理解

<? super A> 也叫超类型通配符,声明通配符是有哪个特性的基类为界定的,也就是A是通配符的子类,不能对泛型参数给出超类型边界,比如<T super A>这是错的,下图报错是因为通配符所匹配的子类仅仅只是number而已,无法添加Integer类型的,可以改成public static void getData(Box<? super Integer> data) { System.out.println("data :" + data.getData()); }

关于java泛型的理解