假定我们有这样一个需求:写一个排序方法,能够对整形数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?
使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。
你可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。
下面是定义泛型方法的规则:
public class Genericity<T> { private T t; //空参构造函数 public Genericity() { } //带有T类型参数的构造函数 public Genericity(T t) { this.t = t; } //打印 public void print(T t){ System.out.println(t); } public static void main(String[] args) { //打印Integer类型 Genericity<Integer> intGen = new Genericity<Integer>(); intGen.print(360); //打印String类型 Genericity<String> strGen = new Genericity<String>(); strGen.print("Hello World"); } }
public class Genericity<T,V> { //空参构造函数 public Genericity() { } //打印 public void print(T t, V v){ System.out.println(t + " : " + v); } public static void main(String[] args) { //打印<Integer,String>类型 Genericity<Integer,String> intGen = new Genericity<Integer,String>(); intGen.print(360,"Hello World"); } }
//泛型接口 interface InterfaceGen<T> { T getT(); void setT(T t); } public class Genericity implements InterfaceGen<Integer> { private Integer t; //空参构造函数 public Genericity() { } //获取值 public Integer getT(){ return t; } //设置t的值 public void setT(Integer t) { this.t = t; } public static void main(String[] args) { Genericity gen = new Genericity(); gen.setT(18); System.out.println(gen.getT()); } }
import java.util.ArrayList; import java.util.List; public class Genericity { public static void main(String[] args) { ArrayList<Worker> workers = new ArrayList<>(); workers.add(new Worker("zhangsan", 18)); workers.add(new Worker("lisi", 22)); workers.add(new Worker("wangwu", 31)); printList(workers); ArrayList<Integer> integers = new ArrayList<>(); integers.add(3); integers.add(9); integers.add(81); printList(integers); } public static void printList(List<?> list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } } class Worker { String name; int age; public Worker(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Worker{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
打印结果:
Worker{name='zhangsan', age=18} Worker{name='lisi', age=22} Worker{name='wangwu', age=31} 3 9 81
/** * 在我们类中方法上定义泛型 * 1、如果类上面定义了泛型,可以直接使用类上面定义的泛型 * 2、如果方法有返回值,而且返回值不确定是什么类型,我们也可以使用泛型来作为方法的返回值 * 返回值的类型不一定和我们类上面的泛型一直 * 3、如果方法是静态方法的时候,那么就需要在static和返回值中间指定要使用的泛型 * 我们发现,泛型也是有局限性的:一旦指定类上的泛型之后,在方法调用的时候就只能使用指定类型 * * @param <T> */ class Tool<T> { public void print(T t) { System.out.println("print :" + t); } /** * 方法的泛型,避免了和类上面定义的泛型的一致,做到了调用的灵活性 * * @param <E> * @param e */ public <E> void show(E e) { System.out.println("show :" + e); } /** * 定义了有返回值的方向方法 * * @param <E> * @param e * @return */ public <E> E show1(E e) { return e; } /** * 如何在没有返回值的静态方法上定义泛型 * * @param <T> * @param t */ public static <T> void show2(T t) { System.out.println("show2 :" + t); } /** * 如何在静态有返回值的方法上定义泛型 * * @param <T> * @param t * @return */ public static <T> T show3(T t) { return t; } }
? extends E:接收E类型或者E的子类型
程序示例:
/** * 在我们类中方法上定义泛型 * 1、如果类上面定义了泛型,可以直接使用类上面定义的泛型 * 2、如果方法有返回值,而且返回值不确定是什么类型,我们也可以使用泛型来作为方法的返回值 * 返回值的类型不一定和我们类上面的泛型一直 * 3、如果方法是静态方法的时候,那么就需要在static和返回值中间指定要使用的泛型 * 我们发现,泛型也是有局限性的:一旦指定类上的泛型之后,在方法调用的时候就只能使用指定类型 * * @param <T> */ class Tool<T> { public void print(T t) { System.out.println("print :" + t); } /** * 方法的泛型,避免了和类上面定义的泛型的一致,做到了调用的灵活性 * * @param <E> * @param e */ public <E> void show(E e) { System.out.println("show :" + e); } /** * 定义了有返回值的方向方法 * * @param <E> * @param e * @return */ public <E> E show1(E e) { return e; } /** * 如何在没有返回值的静态方法上定义泛型 * * @param <T> * @param t */ public static <T> void show2(T t) { System.out.println("show2 :" + t); } /** * 如何在静态有返回值的方法上定义泛型 * * @param <T> * @param t * @return */ public static <T> T show3(T t) { return t; } }
? super E:接收E类型或E的超(父|基)类
//使用上例的Animal和Dog类
public class Genericity { public static void main(String[] args) { ArrayList<Animal> animals = new ArrayList<Animal>(); animals.add(new Animal()); animals.add(new Animal()); sop(animals); } //这里使用了泛型中类型通配符的向下限定 :? 对应的类型必须为Dog类或Dog的父类 public static void sop(List<? super Dog> list){ for (int i = 0; i < list.size(); i++) { Object o = list.get(i); } } }