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());
}
}
运行结果如下:
需要注意的是,我们在定义对象的时候,已经将变量的类型给确定了,这个时候可以对对象里面的属性进行赋值操作,但是如果在定义对象的时候使用通配符,即 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());
}
}
运行结果如下
我们在方法里面接受对象的时候,定义类泛型类里面的泛型是 Number 的子类,所以如果我们如果使用 String 类型的话,编译期间就会报错,如下:
定义一个设置上限类的泛型类
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("结束");
}
}
运行结果如下:
在定义类的时候就已经将泛型的上限确定,是 Number 类型的子类,如果定义对象的时候,声明成 String 类型,那么就会编译异常,如下图:
定义一个普通类
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());
}
}
运行结果如下:
我们在定义对象的时候,使用类 super 表示该泛型对象是 String 的类或者父类。如果在定义对象的时候,我们指定为 Integer 类型,就会编译报错
泛型通配符可以将对象的类型任意化,而不是固定的那个类。这样让代码更加的灵活,更加的适配更多场景。通过泛型通配符,我们还可以设置泛型的上限和下限,这样可以粗粒度的控制我们的对象类型。