为什么要用泛型?
泛型程序的设计主要是为了编写的代码可以被不同的对象重用。
最简单的例子就是ArrayList。我们不能为每个对象写一个ArrayList,为了适用于所有对象,ArrayList被设计为泛型类。有人说不用泛型,用Object不就可以了?但是用Object,意味着在具体对象面前你又要强制类型转换。
泛型类
泛型类就是又一个或多个类型变量的类。
下面定义一个泛型的坐标类。
public class Point<T> { private T x; private T y; public T getX() { return x; } public void setX(T x) { this.x = x; } public Point(T x, T y) { this.x = x; this.y = y; } public Point() { } }
这样我们可以传入自己需要的类型,如:
Point<Integer> point1 = new Point<>(1,1); Point<Float> point2 = new Point<>(1f,1f);
泛型方法
泛型方法是指带有类型参数的方法。
class ArrayUtil{ public static <T> T getMiddle(T[] array){ return array[array.length/2]; } }
泛型接口
泛型接口和泛型类用法一样,如:
public interface JavaBeanCRUD<T> { T getObjectById(String id); void addObject(T obj); void delObjById(String id); void updateObj(T obj); }
public interface StudentDao extends JavaBeanCRUD<Student> { }
public class StudentDaoImpl implements StudentDao { @Override public Student getObjectById(String id) { return null; } @Override public void addObject(Student obj) { } @Override public void delObjById(String id) { } @Override public void updateObj(Student obj) { } }
简单的例子我们能看到泛型确实给我们减少了代码的重写。
类型变量的限定
如果我们需要写一个方法,实现获取集合中最大值,即用到compareTo接口。我们可以用extends限制变量的类型。如:
public static <T extends Comparable> T getMax(T[] array){ if(array==null || array.length==0) return null; T max = array[0]; for(T temp : array){ if(max.compareTo(temp)<0) max = temp; } return max; }
extends这里不再是我们熟悉的继承的意思了。这里约束了getMax这个方法传入的对象必须继承Comparable,否则会有编译上的错误。
一个类型变量或通配符可以有多个限定,限定之间用 ‘&’ 分开即可,如:
T extends Comparable & Serializable