通配符
通配符解决的是:一个方法可以接收所有的泛型类型,但是又不能够让用户随意修改。
?通配符:作用于方法参数声明:
public static void print(MyClass<?> myClass){
}
为什么 有通配符?
在类中追加了泛型的定义后,避免了ClassCastException的问题,但是又会产生新的情况:参数的统一问题
什么 意思???看一段代码解释:
这段代码用泛型定义了一个Message类,在主类里写了个方法打印Message创建的对象的message属性
class Message<T> {
private T message;
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
public class 通配符 {
public static void main(String[] args) {
Message<String> message = new Message<>();
message.setMessage("hello");
method(message);
}
public static void method(Message<String> str){
System.out.println(str);
}
}
看上去没有问题,那么void main里new了一个Integer类型的message怎么办?调用method方法就会报错
public class 通配符 {
public static void main(String[] args) {
Message<Integer> message = new Message<>();
message.setMessage(123);
method(message);//这里就会报错
}
public static void method(Message<String> str){
System.out.println(str);
}
}
那么改一下,使用通配符就可以解决问题
public class 通配符 {
public static void main(String[] args) {
Message<Integer> message = new Message<>();
message.setMessage(123);
method(message);
}
public static void method(Message<?> str){
System.out.println(str);
}
}
此时方法参数表示可以接受任意类型的Message对象。
使用通配符之后无法设置值
由于无法确定入参的类型,因此“?”通配符下的泛型参数,只能取得类中的属性值,无法进行属性值的设置。
public class 通配符 {
public static void main(String[] args) {
Message<Integer> message = new Message<>();
message.setMessage(123);
method(message);
}
public static void method(Message<?> str){
str.setMessage("232");//由于不知道str的具体类型,所以不能修改,会报错
System.out.println(str);
}
}
无法设置值的解决方案——上下限概念
在"?"的基础上又产生了两个子通配符:
? extends class:设置泛型上限:
例如:? extends Number,表示只能够设置Number或其子类,例如:Integer、Double等;
? super class:设置泛型下限:
例如:? super String,表示只能够设置String及其父类Object。
设置泛型上限——可以用于泛型类的声明,也可用于方法参数。
泛型类上限声明:(T必须是Number类的子类)
//设置上限
class Message<T extends Number> {
private T message;
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
方法参数声明上限:表示方法入参只能接受Num以及他的子类对象。
public static void method(Message<? extends Number> str){
str.setMessage("232");//此时仍然无法确定str的具体类型,所以不能修改,会报错
System.out.println(str);
}
方法参数设置泛型上限仍然只能取得类中属性值,而无法设置,因为父类的值子类不一定能使用(父类不一定能发生向下转型变为子类)。
设置泛型下限——只能用于方法参数
下限声明:? Super 类(>=类):都表示方法入参只能接受类及其父类对象
public static void method(Message<? super Integer> str){
str.setMessage(256);//现在可以设置了,因为子类可以天然向上转型
System.out.println(str);
}
方法参数设置泛型下限不仅可以取得类中属性值,还可以设置属性值。因为子类可以天然向上转型变成父类。