📅  最后修改于: 2023-12-03 15:32:02.330000             🧑  作者: Mango
Java中的通配符是指在泛型中使用的符号'?'。与我们使用的'*'类似,它可以代表任何类型。本文将对Java中的通配符进行详细介绍。
通配符可以用来限制泛型类型的范围。它可以代表任何类型,但并不意味着泛型可以接受任何类型。
例如,我们定义一个泛型类Box
:
public class Box<T> {
private T item;
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
}
这个类可以接受任何类型的对象。我们可以定义一个Box
对象来存储整数:
Box<Integer> intBox = new Box<>();
intBox.setItem(5);
Integer item = intBox.getItem();
但如果我们想要定义一个Box
对象来存储任何类型的对象,该怎么办呢?这时候就需要使用通配符了:
Box<?> anyBox = new Box<>();
这里的'?'就是通配符,它可以代表任何类型。但是,由于我们不知道Box
存储的是什么类型的对象,所以我们只能使用一些基本方法,例如getItem()
和setItem()
。
虽然通配符可以代表任何类型,但它并不能接受任何类型。
例如:
Box<?> anyBox = new Box<>();
anyBox.setItem(5); // 编译错误,setItem()方法无法接受类型为int的参数
这是因为通配符会使泛型类型丢失,Java编译器并不知道要将'?'替换成什么类型。为了避免这种情况,可以使用有限制的通配符。
有限制的通配符使用extends
关键字来设置限制,表示通配符可以接受限制范围内的子类。
例如:
public class Animal {...}
public class Cat extends Animal {...}
Box<? extends Animal> animalBox = new Box<>();
animalBox.setItem(new Animal()); // 编译错误,setItem()方法无法接受类型为Animal的参数
animalBox.setItem(new Cat()); // 正确,setItem()方法接受类型为Cat的子类参数
这里的通配符表示Box
对象可以接受继承自Animal
的子类。
通配符的限制不仅适用于参数类型,还适用于返回类型。这意味着带通配符的方法也必须受到限制,返回类型必须是通配符的上限。
例如:
public class Box<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public Box<?> boxCopy() {
Box<?> copyBox = new Box<?>();
copyBox.setItem(this.getItem());
return copyBox;
}
}
这里的boxCopy()
方法返回一个新的Box
对象,它的类型和原来的Box
对象相同。由于Box
对象的类型可能是任何类型,因此我们必须使用带通配符的泛型类型来定义它。但是,由于通配符不能接受任何类型,所以我们必须使用通配符的上限来定义返回类型,否则会发生编译错误。
Java中的通配符可以用来限制泛型类型的范围。它可以代表任何类型,但并不意味着泛型可以接受任何类型。有限制的通配符使用extends
关键字来设置限制,表示通配符可以接受限制范围内的子类。通配符的限制不仅适用于参数类型,还适用于返回类型。带通配符的泛型类型必须使用通配符的上限来定义返回类型。