Java泛型通配符

Java泛型通配符教程

Java 语言 是面向对象编程语言,在编程过程中对象的引用传递是最常见的。在泛型类的操作中,如果遇到了泛型的引用传递,那么必须要类型匹配才可以传递。那么实在是想让泛型引用传递,该怎么办呢?

我们可以使用通配符 " ? ",表示可以接收此类型的任意泛型对象。

Java泛型通配符

案例

定义一个泛型类

package com.haicoder.net.paradigm; public class Point<T> { private T key; public T getKey() { return key; } public void setKey(T key) { this.key = key; } }

定一调用的测试类

package com.haicoder.net.paradigm; public class TestParadigm { public static void main(String[] args) { System.out.println("嗨客网(www.haicoder.net)"); Point<String> paramPoint = new Point<>(); paramPoint.setKey("欢迎来到嗨客网"); printInfo(paramPoint); System.out.println("结束"); } private static void printInfo(Point<?> point) { System.out.println(point.getKey()); } }

运行结果如下:

04 泛型通配符.png

需要注意的是,我们在定义对象的时候,已经将变量的类型给确定了,这个时候可以对对象里面的属性进行赋值操作,但是如果在定义对象的时候使用通配符,即 Point<?> paramPoint = new Point<>(); 这样的方式,那么在给对象赋值的时候,是不能够给对象里面的参数赋值的,只能设置为 null。

因为 java 语言里面的任何类的对象都可以置为 null。

泛型设置上限下限详解

定义

在创建对象或者声明类的时候,我们可以指定我们范型的对应的类型的上限和下限。泛型上限表示范型的类型可能是所指定的类型或者此类型的子类。

泛型的下限表示此泛型指定的类可以是指定的类型,也可以是该类型的父类型,或者类始祖 Object 类。

语法

设置上限

类名称<? extends 类> 对象名称 // 定义一个对象 [访问权限] 类名称 <泛型标识 extends 类>{} //声明类

设置下限

类名称<? super 类> 对象名称 //定义一个对象

说明

和定义普通的泛型对象和声明普通的泛型类一样,只不过特殊的地方在于使用了通配符来 extend 或者 super 某个类。将泛型对应的类的范围变大。

案例

上限定义对象案例

定义一个普通泛型类

package com.haicoder.net.paradigm; public class Point<T> { private T key; public T getKey() { return key; } public void setKey(T key) { this.key = key; } }

定义一个测试类

package com.haicoder.net.paradigm; public class TestParadigm { public static void main(String[] args) { System.out.println("嗨客网(www.haicoder.net)"); Point<Integer> paramPoint = new Point<>(); paramPoint.setKey(100); printInfo(paramPoint); System.out.println("结束"); } private static void printInfo(Point<? extends Number> point) { System.out.println(point.getKey()); } }

运行结果如下

06 泛型上限对象.png

我们在方法里面接受对象的时候,定义类泛型类里面的泛型是 Number 的子类,所以如果我们如果使用 String 类型的话,编译期间就会报错,如下:

05 泛型上限.png

上限定义类案例

定义一个设置上限类的泛型类

package com.haicoder.net.paradigm; public class Point<T extends Number> { private T key; public T getKey() { return key; } public void setKey(T key) { this.key = key; } }

定义一个测试类

package com.haicoder.net.paradigm; public class TestParadigm { public static void main(String[] args) { System.out.println("嗨客网(www.haicoder.net)"); Point<Integer> paramPoint = new Point<>(); paramPoint.setKey(100); System.out.println("嗨客网争做 : " + paramPoint.getKey() + " 年企业: "); System.out.println("结束"); } }

运行结果如下:

08 范型类运行结果.png

在定义类的时候就已经将泛型的上限确定,是 Number 类型的子类,如果定义对象的时候,声明成 String 类型,那么就会编译异常,如下图:

07 泛型上限类编译错误.png

下限定义对象案例

定义一个普通类

package com.haicoder.net.paradigm; public class Point<T> { private T key; public T getKey() { return key; } public void setKey(T key) { this.key = key; } }

定义一个测试类

package com.haicoder.net.paradigm; public class TestParadigm { public static void main(String[] args) { System.out.println("嗨客网(www.haicoder.net)"); Point<String> paramPoint = new Point<>(); paramPoint.setKey("嗨客网"); printInfo(paramPoint); System.out.println("结束"); } private static void printInfo(Point<? super String> point) { System.out.println(point.getKey()); } }

运行结果如下:

10 下限泛型运行结果.png

我们在定义对象的时候,使用类 super 表示该泛型对象是 String 的类或者父类。如果在定义对象的时候,我们指定为 Integer 类型,就会编译报错

09 泛型下限编译异常.png

Java泛型通配符总结

泛型通配符可以将对象的类型任意化,而不是固定的那个类。这样让代码更加的灵活,更加的适配更多场景。通过泛型通配符,我们还可以设置泛型的上限和下限,这样可以粗粒度的控制我们的对象类型。