泛型就是指在定义类,接口时指定类型参数,这个类型形参将在声明变量,创建对象时确定。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.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; } }
例如下面的类定义中的泛型表示:只能接收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()); } }
例如下面代码中的方法定义:
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); }
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); } }
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>.