扒一拔:Java 中的泛型(一) (2)

如上所示, 其中 是不能省略的。 而且可以是多种类型, 如 <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 为例

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]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxxdj.html