如上所示, 其中 是不能省略的。 而且可以是多种类型, 如 <K, V>
public class Util { public static <K, V> boolean sameType(K k, V v) { return k.getClass().equals(v.getClass()); } } 2.4.2 泛型方法的调用调用时, 在方法之前指定参数的类型
@Test public void equalsMethod(){ boolean same = EqualMethodClass.<Integer>equals(1,1); System.out.println(same); } 3 类型变量边界 3.1 定义如果我们需要指定类型是某个类(接口)的子类(接口)
<T extends BundingType>使用 extends , 表示 T 是 BundingType 的子类, 两者都可以是类或接口。
此处的 extends 和继承中的是不一样的。
如果有多个边界限定:
<T extends Number & Comparable>使用的是 & 符号。
注意事项
如果边界类型中有类, 则类必须是放在第一个
也就是说
<T extends Comparable & Number> // 编译错误会报错
3.2 示例有时, 我们需要对类型进行一些限定, 比如说, 我们要获取数组的最小元素
public class ArrayUtils { public static <T> T min(T[] arr) { if (arr == null || arr.length == 0) { return null; } T smallest = arr[0]; for (int i = 0; i < arr.length; i++) { if (smallest.compareTo(arr[i]) > 0) { smallest = arr[i]; } } return smallest; } }上面的是报错的。 因为, 在该函数中, 我们需要使用 compareTo 函数, 但是, 并不是所欲的类都有这个函数的。 因此, 我们可以这样子限定
将 转换成 <T extends Comparable 即可。
测试
@Test public void testMin() { Integer a[] = {1, 4, 5, 6, 0, 2, -1}; Assertions.assertEquals(ArrayUtils.<Integer>min(a), Integer.valueOf(-1)); } 4 泛型, 继承和子类型 4.1 泛型和继承在 Java 继承中, 如果变量 A 是 变量 B 的子类, 则我们可以将 A 赋值给 B。 但是, 在泛型中则不能进行类似的赋值。
对继承来说, 我们可以这样做
public class Box<T> { List<T> boxs = new ArrayList<>(); public void add(T element) { boxs.add(element); } public static void main(String[] args) { Box<Number> box = new Box<Number>(); box.add(new Integer(10)); // OK box.add(new Double(10.1)); // OK } }但是, 在泛型中, Box 不能赋值给 Box(即两个不是子类或父类的关系)。
可以使用下图来进行阐释
注意:
对于给定的具体类型 A 和 B(如 Number 和 Integer), MyClass 与 MyClass 没有任何的关系, 不管 A 和 B 之间是否有关系。
4.2 泛型和子类型在 Java 中, 我们可以通过继承或实现来获得一个子类型。 以 Collection 为例
由于 ArrayList 实现了 List, 而 List 继承了Collection。 因此, 只要类型参数没有更改(如都是 String 或 都是 Integer), 则类型之间子父类关系会一直保留。
5 类型推断类型推断并不是什么高大上的东西, 我们日常中其实一直在用到。它是 Java 编译器的能力, 其查看每个方法调用和相应声明来决定类型参数, 以便调用时兼容。
值得注意的是, 类型推断算法仅仅是在调用参数, 目标类型和明显的预期返回类型时使用。
5.1 类型推断和泛型方法在下面的泛型方法中
public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } } public class BoxDemo { public static <U> void addBox(U u, List<Box<U>> boxes) { Box<U> box = new Box<>(); box.set(u); boxes.add(box); } public static <U> void outputBoxes(List<Box<U>> boxes) { int counter = 0; for (Box<U> box: boxes) { U boxContents = box.get(); System.out.println("Box #" + counter + " contains [" + boxContents.toString() + "]"); counter++; } } public static void main(String[] args) { ArrayList<Box<Integer>> listOfIntegerBoxes = new ArrayList<>(); BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes); BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes); BoxDemo.addBox(Integer.valueOf(30), listOfIntegerBoxes); BoxDemo.outputBoxes(listOfIntegerBoxes); } }输出
Box #0 contains [10] Box #1 contains [20] Box #2 contains [30]