泛型就是指在定义类,接口时指定类型参数,这个类型形参将在声明变量,创建对象时确定。JDK1.5添加了泛型支持。
1. 简单的泛型示例:
public class Temp {
public static void main(String[] args) {
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <Float> r2 = new Rectangle <Float> (3.1f, 5.1f);
System.out.println(r1.getLength() instanceof Integer); //输出true
System.out.println(r2.getLength() instanceof Float); //输出true
}
}
class Rectangle <T> { //矩形类,长和宽可能是int型,也可能是float型等等
private T length;
private T width;
public Rectangle(T length, T width) {
this.length = length;
this.width = width;
}
public T getLength() {
return length;
}
}
2. 泛型通配符
2.1 ? : 表示可以接收任意类型。但只是接收和输出,不能修改类的属性。
public class Temp {
public static void main(String[] args) {
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <Float> r2 = new Rectangle <Float>(3.1f,5.1f);
Temp temp = new Temp();
temp.printInfo(r1);
temp.printInfo(r2);
}
public void printInfo (Rectangle <?> r) { //表示可以接受任何种类的Rectangle类。如果不加泛型,则会提示警告信息。
r.setLength(1); //报错:因为不能确定?的类型,因此不能使用setLength这种改变属性的方法。
System.out.println(r.getLength());
}
}
class Rectangle <T> { //矩形类,长和宽可能是int型,也可能是float型等等
private T length;
private T width;
public Rectangle(T length, T width) {
this.length = length;
this.width = width;
}
public T getLength() {
return length;
}
public void setLength(T length) {
this.length = length;
}
}
2.2 ? extends 父类: 表示可以接收的类的最高上限。
例如下面的类定义中的泛型表示:只能接收Number类及其子类。
class Rectangle <T extends Number>
也例如下面代码中的方法定义:
public class Temp {
public static void main(String[] args) {
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <Float> r2 = new Rectangle <Float>(3.1f,5.1f);
Rectangle <String> r3 = new Rectangle <String> ("3", "5");
Temp temp = new Temp();
temp.printInfo(r1);
temp.printInfo(r2);
temp.printInfo(r3); //报错:因为只能接收Rectangle <? extends Number>的类型
}
public void printInfo (Rectangle <? extends Number> r) {
System.out.println(r.getLength());
}
}
2.3 ? super 子类: 表示可以接收的类的最低下限。
例如下面代码中的方法定义:
public class Temp {
public static void main(String[] args) {
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <Object> r2 = new Rectangle <Object>(3.1f,5.1f);
Rectangle <String> r3 = new Rectangle <String> ("3", "5");
Temp temp = new Temp();
temp.printInfo(r1); //报错:只能接收Rectangle <? super String>的类。
temp.printInfo(r2);
temp.printInfo(r3);
}
public void printInfo (Rectangle <? super String> r) {
System.out.println(r.getLength());
}
}
3. 泛型接口
3.1 泛型接口的定义语法: interface 接口名称 <泛型类型1, 泛型类型2...>
例如:
interface Shape <K,V> { //定义泛型接口
public void printInfo (K k_param, V v_param);
}
3.2 泛型接口的第一种实现方式:不指定具体的泛型类型
public class Temp {
public static void main(String[] args) {
Rectangle <String, Integer> r = new Rectangle <String, Integer> ();
r.printInfo("矩形", 5); //输出:Info: 矩形, 5
}
}
interface Shape <K,V> { //定义泛型接口
public void printInfo (K k_param, V v_param);
}
class Rectangle <K,V> implements Shape <K,V> { //实现泛型接口,不指定具体的泛型类型
public void printInfo(K k_param, V v_param) {
System.out.println("Info: " + k_param + ", " + v_param);
}
}
3.3 泛型接口的第二种实现方式:指定具体的泛型类型
public class Temp {
public static void main(String[] args) {
Rectangle r = new Rectangle ();
r.printInfo("矩形", 5); //输出:Info: 矩形, 5
}
}
interface Shape <K,V> { //定义泛型接口
public void printInfo (K k_param, V v_param);
}
class Rectangle implements Shape <String,Integer> { //实现泛型接口,指定具体的泛型类型
public void printInfo(String s, Integer i) {
System.out.println("Info: " + s + ", " + i);
}
}
4. 泛型方法
使用简单的泛型方法示例:
public class Temp {
public static void main(String[] args) {
Gen g = new Gen();
g.printInfo(1); //这是传入的参数是Integer型
g.printInfo("字符串"); //这是传入的参数是String型
}
}
class Gen { //定义类的时候没有使用泛型
public <T> void printInfo(T param) { //定义方法时使用泛型
System.out.println(param);
}
}
使用泛型方法返回数组示例:
public class Temp {
public static void main(String[] args) {
Integer i1 [] = {1,2,3,4,5};
String i2 [] = {"1","2","3"};
Gen g = new Gen();
for (int x: g.getInfo(i1)) { //输出:12345
System.out.print(x);
}
System.out.println("");
for (String x: g.getInfo(i2)) { //输出:123
System.out.print(x);
}
}
}
class Gen { //定义类的时候没有使用泛型
public <T> T[] getInfo(T ... param) { //定义方法时使用泛型
return param; //返回类型为T的数组
}
}
5. 泛型的嵌套
public class Temp {
public static void main(String[] args) {
Info <String> info = new Info <String> ("Info类信息");
Person <Info<String>> person = new Person <Info<String>> (info); //泛型的嵌套使用
System.out.println(person.getInfo()); //输出: Info@1fb8ee3
}
}
class Info <T> {
private T param;
public Info(T param) {
this.param = param;
}
}
class Person <T> {
private T info;
public Person(T info) {
this.info = info;
}
public T getInfo() {
return this.info;
}
}
6. 泛型注意事项
6.1 泛型中必须是引用类型。
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <int> r2 = new Rectangle <int> (3,5); //报错:Syntax Error on token "int".
Rectangle <Integer> r1 = new Rectangle <Integer> (3,5);
Rectangle <Object> r2 = new Rectangle <Object> (3,5);
r2 = r1; //报错:Type mismatch: cannot convert from Rectangle<Integer> to Rectangle<Object>.