步步理解 JAVA 泛型编程(一)

JDK 1.5 相对于 JDK 1.4 来说变化最大的部分就是泛型,甚至可以说自 Java 1.0 发布以来也是最大的一次语言变化,因为要涉及到编译器的大改动。很早的时候大家对泛型的呼声很大,正如 C++ 的模板,C# 的泛型确实是个值得借鉴的好特性。JDK1.5 这前,很多人对于泛型是急不可耐,在 JDK1.4 下搭配一个外挂的 Generic Java 编译器,通老实 -Xbootclasspath、-bootclasspath 同样能让你在 1.4 的 JDK 上使用泛型:

javac -J-Xbootclasspath/p:JSR14HOME\gjcrt.jar -bootclasspath JSR14HOME\collect.jar;JDK141HOME\jre\lib\rt.jar -source 1.5 FileName.java
java -Xbootclasspath/p:JSR14HOME\gjc-rt.jar FileName

JDK 1.5 虽说出来这么久了,JDK 7 眼看都要见得天日了,不过可能我们很多人也只是知道怎么使用支持泛型的集合,也许还没有写过自己的泛型类,更不用说泛型的一些更高阶规范了。正如我们会在 Hibernate、Spring 里很熟练的使用零配置的注解,好像也很少有机会让我们去写处理注解的代码似的。因为毕竟我们不是书写框架的,多数时候是在应用它们。

多看JDK 的源代码固然是个好办法,但除看之外,练手帮助理解是必不可少的。如果你熟悉 C++,可以与 C++ 的模板类比。现在来一步步了解泛型。首先泛型这一称谓听来有点抽象,换作参数化类型,或者借用模板类的叫法会好理解的多。

比如说这样一个泛型类:

声明部分 public class Demo<T> 为 Demo 类指定了一个类型参数 T,那么在该方法就可以使用该类型 T,如作为实例、局部变量,方法参数或返回值。

实际使用该类时 T 要被替换为具体的类型,如类型为 String,用 Demo<String> demo= new Demo<String>() 声明构造,那么上面的变量及方法的原型分别是:

String first;
String getFirst();
void setFirst(String first);

如果具体类型为 Integer,用 Demo<Integer> demo = new Demo<Integer>() 声明构造,则上面的变量及方法的原型分别是:

Integer first;
Integer getFirst();
void setFirst(Integer first);

可以是任何的具体类型,所以可以理解为泛型类是普通类的工厂。其实依照 C++ 的名词,前面类的定义称之为一个模板类,使用的时候是让模板中的类型具体化,这样好理解些。但要记得,Java 的泛型与 C++ 的模板实现的泛型内部机制还是有本质区别的。

前面是在类的声明部分定义了一个类型参数,如果有如个类型参数也是可以的,写成

public class Demo<T,U>,多少个都行 public class Demo<T,U,S>,在类的变量或方法中可以使声明部分定义的类型。

类型用大写形式,一般都是用 T 指代 Type,K 指代 Key,V 指代 Value,其他靠着 T 的 U,S ...... 都随意用了。

不妨来看个 C++ 的模板类,以及使用代码:

参考:1. Using Java Generics

本文链接 https://yanbin.blog/understand-java-generic-1/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

3 Comments
Inline Feedbacks
View all comments
cxh8318
cxh8318
14 years ago

写的通俗易懂,不错,但有些错别字:

1、声明部分 public class Demo<T> 为 Demo 类指定了一个类型参数 T,那么在该方法就可以使用该类型 T,如作为就是,方法参数或返回值。

2、前面是在类的声明部分定了一个类型参数,如果有如个类型参数也是可以的,写成

小人物
14 years ago

不错,顶一下,期待楼主写泛型的高阶应用。

隔叶黄莺
14 years ago

谢谢各位的关注,更要感谢cxh8318的提醒,文字错误的地方已改过来了。