java泛型(一)

来源:互联网 发布:济南网络系统集成商 编辑:程序博客网 时间:2024/03/29 04:15

Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter)。声明的类型参数在使用时用具体的类型来替换,现在泛型最主要的应用是在JDK5中的新集合类框架中,Map, List均有用到。其中的优点不言而喻,我们可以横向扩展更多的类,缺点呢,其实也就是他的优点,因为这需要我们在使用泛型类的时候,要很清楚自己的代码目地,不能使用错误的类型。

最基本的泛型类

/** * 最基本的泛型类,类型由自己定义 * @author dhb * * @param <T> */public class Point<T> {private T var;public T getVar() {return var;}public void setVar(T var) {this.var = var;}}public class GenericExample {public static void main(String[] args) {Point<String> p = new Point<String>();p.setVar("coder");System.out.println(p.getVar());}}

多个泛型类型

/** * 多个泛型类型,一般多个最好是以靠近T的字母,如S,R等 * @author dhb * * @param <T> * @param <S> */public class Notepad<T, S> {private T key;private S value;public T getKey() {return this.key;}public S getValue() {return this.value;}public void setKey(T key) {this.key = key;}public void setValue(S value) {this.value = value;}}public class GenericExample {public static void main(String[] args) {Notepad<String, Integer> p = new Notepad<String, Integer> ();p.setKey("coder");p.setValue(99999);System.out.println("key: " + p.getKey());System.out.println("value: " + p.getValue());}}

在方法参数中使用通配符"?"

/** * 该例子关键在main方法里 * @author dhb * @param <T> */public class Info<T> {private T key;public T getKey() {return this.key;}public void setKey(T key) {this.key = key;}@Overridepublic String toString() {return this.key.toString();}}public class GenericExample {public static void main(String[] args) {Info<String> i = new Info<String>();i.setKey("coder");fun(i);Info<Integer> j = new Info<Integer>();j.setKey(9999);fun(j);}public static void fun(Info<?> temp) {System.out.println("Content: " + temp);}}

向上转型失败

/** * 该例子关键在main方法里 * @author dhb * @param <T> */public class Info<T> {private T key;public T getKey() {return this.key;}public void setKey(T key) {this.key = key;}@Overridepublic String toString() {return this.key.toString();}}public class GenericExample {public static void main(String[] args) {Info<String> strEg = new Info<String>();Info<Object> objEg;// 编译错误"Type mismatch: cannot convert from Info<String> to Info<Object>"// 向上转型失败,String -> Object//objEg = strEg;}}

泛型在接口中的使用

interface Info<T> {public T getVar();}public class InfoImpl<T> implements Info<T> {private T var;public InfoImpl(T var) {this.setVar(var);}public void setVar(T var) {this.var = var;}public T getVar() {return this.var;}}
public class InfoImpl1 implements Info<String> {private String var;public InfoImpl1(String var) {this.setVar(var);}public void setVar(String var) {this.var = var;}public String getVar() {return this.var;}}
public class GenericExample {public static void main(String[] args) {Info<String> strEg = new InfoImpl<String>("coder");System.out.println("Content: " + strEg.getVar());Info<String> strEg1 = new InfoImpl1("coder1");System.out.println("Content: " + strEg1.getVar());}}

通配符和extends, super的使用

/** * 该例子关键在main方法里 * @author dhb * @param <T> */public class Info<T> {private T key;public T getKey() {return this.key;}public void setKey(T key) {this.key = key;}@Overridepublic String toString() {return this.key.toString();}}public class GenericExample {public static void main(String[] args) {Info<String> strEg = new Info<String>();strEg.setKey("coder");Info<Integer> intEg = new Info<Integer>();intEg.setKey(9999);// upTypeLimit(i);// 使用Integer,Number类型均可以upTypeLimit(intEg);// 编译报错"The method downTypeLimit(Info<? super String>) in the type// GenericExample is not applicable for the arguments (Info<Integer>)"// downTypeLimit(intEg);// 由于使用的是super,downTypeLimit只能接收String本身和Object// 查看了String的继承关系,没有继承其他类,只有ObjectdownTypeLimit(strEg);Info<Object> objEg = new Info<Object>();objEg.setKey(9999);downTypeLimit(objEg);}/** *  * <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 *  * @param temp *  */public static void upTypeLimit(Info<? extends Number> temp) {System.out.println("Content: " + temp);}/** *  * <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object * 在此例中,表示T只能为Object或String,因为String只继承于Object *  * @param temp *  */public static void downTypeLimit(Info<? super String> temp) {System.out.println("Content: " + temp);}}

伪泛型

不存在真正的泛型类,泛型类对Java虚拟机来说是透明的.JVM并不知道泛型类的存在,换句话来说,JVM处理泛型类和普通类没什么区别的.因此在静态方法、静态初始化块、静态变量里面不允许使用类型形参。- 以下方式都是错误的

private static T data;static {T f;}public static void func() {T name = 1;}

下面的例子可以从侧面验证不存在泛型类

public static void main(String[] args) {List<String> a1 = new ArrayList<>();List<Integer> a2 = new ArrayList<>();System.out.println(a1.getClass() == a2.getClass());System.out.println(a1.getClass());System.out.println(a2.getClass());}

输出:

        true  
        class java.util.ArrayList
        class java.util.ArrayList

0 0