11.泛型
能否只定义一个类就能满足坐标既可能为int类型,也可能为double类型的情况呢?如果可以的话将可以让代码更加通用,减少大量的重复代码。答案是肯定的,这个时候你需要泛型。
发型类
在使用泛型时,我们可以把类型作为参数传入到泛型类中。类似于把参数传入到方法中一样。我们来实现一个通用的泛型Point类:
1 public class Point<T> { 2 private T x; 3 private T y; 4 5 public T getX() { 6 return x; 7 } 8 9 public void setX(T x) { 10 this.x = x; 11 } 12 13 public T getY() { 14 return y; 15 } 16 17 public void setY(T y) { 18 this.y = y; 19 } 20 }
此时Point成为了一个泛型类,T是则是类型参数,T具体是什么类型那要看程序运行的时候我们传入什么类型给他。
使用泛型类时,注意实际传入的类型参数不能是原生类型,必须是引用类型,因此如果希望传入int类型的话,那么需要传入int对应的包装类Interger。对应地,double类型则要传入包装类Double。
public class Test{ public static void main(String[] args){ // 坐标为int类型,把int类型的包装类Integer作为参数传入泛型类中 Point<Integer> point1 = new Point<Integer>(); point1.setX(1); point1.setY(1); // 坐标为double类型,把double类型的包装类Double作为参数传入泛型类中 Point<Double> point2 = new Point<Double>(); point2.setX(3.456); point2.setY(4.789); }
多个泛型参数
泛型类支持多个类型参数。比方说我们需要实现一个三元组Triple类,存储三个类型的变量,我们可以实现如下:
1 public class Triple<A, B, C> { 2 private A a; 3 private B b; 4 private C c; 5 6 public A getA() { 7 return a; 8 } 9 10 public void setA(A a) { 11 this.a = a; 12 } 13 14 public B getB() { 15 return b; 16 } 17 18 public void setB(B b) { 19 this.b = b; 20 } 21 22 public C getC() { 23 return c; 24 } 25 26 public void setC(C c) { 27 this.c = c; 28 } 29 30 }
使用Triple类的方式如下:
1 Triple<String, Integer, Float> triple = new Triple<String, Integer, Float>(); 2 triple.setA("something"); 3 triple.setB(1); 4 triple.setC(1.0f);
编译器会根据你的实例化代码以及泛型代码来生成运行时代码
泛型方法
泛型也可以直接应用在一个方法中,不要求这个方法所属的类为泛型类。例如我们要获取一个对象的类名称:
1 public class Printer { 2 public static <T> void printArray(T[] objects) { 3 if (objects != null) { 4 for(T element : objects){ 5 System.out.printf("%s",element); 6 } 7 } 8 } 9 10 public static void main(String[] args) { 11 Integer[] intArray = { 1, 2, 3, 4, 5 }; 12 Character[] charArray = { 'T', 'I', 'A', 'N', 'M', 'A', 'Y', 'I', 'N', 'G' }; 13 14 printArray(intArray); 15 printArray(charArray); 16 } 17 }
与泛型类不同的是泛型方法需要在方法返回值前用尖括号声明泛型类型名,这样才能在方法中使用这个标记作为返回值类型或参数类型。
浙公网安备 33010602011771号