Java中的不确定类型参数
Java是一种静态类型的编程语言,这意味着在编译时必须明确指定每个变量和参数的类型。然而,有时我们可能需要在代码中使用不确定类型的参数。这样的情况可以通过使用Java的泛型来解决。
泛型概述
Java泛型是一种参数化类型的概念,允许我们在定义类、接口和方法时使用类型参数。这使得代码更加灵活,可以在编译时检查类型安全。
泛型类
我们可以通过在类名后面添加尖括号和类型参数来定义泛型类。下面是一个简单的例子:
class Box<T> {
private T value;
public Box(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
在这个例子中,Box
类有一个类型参数T
,它表示一个未知的类型。构造函数和getValue
方法可以使用T
作为参数类型或返回类型。我们可以在创建对象时指定具体的类型。
Box<String> stringBox = new Box<>(Hello);
String value = stringBox.getValue(); // Hello
泛型接口和方法
除了泛型类,我们还可以定义泛型接口和方法。它们的用法与泛型类类似。
interface Pair<K, V> {
K getKey();
V getValue();
}
class OrderedPair<K, V> implements Pair<K, V> {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
OrderedPair<String, Integer> pair = new OrderedPair<>(One, 1);
String key = pair.getKey(); // One
Integer value = pair.getValue(); // 1
不确定类型的参数
Java中的泛型允许我们使用不确定类型的参数。这对于处理一些通用的操作非常有用,例如比较两个对象的大小或执行某些计算。
通配符
Java泛型提供了通配符(wildcard)来表示不确定类型的参数。通配符使用?
表示。
无限制通配符
在某些情况下,我们只关心参数的类型,而不关心具体的类型。这种情况下,我们可以使用无限制通配符?
。
void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
在这个例子中,printList
方法接受一个List
作为参数,并打印出列表中的所有元素。无限制通配符?
表示我们不关心列表中元素的具体类型。
上界通配符
有时我们对参数的类型有一些限制。例如,我们想要比较两个Person
对象的年龄,但不同类型的对象不能进行比较。
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and setters
}
class Utils {
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
}
Person person1 = new Person(John, 25);
Person person2 = new Person(Jane, 30);
Person maxPerson = Utils.max(person1, person2);
System.out.println(maxPerson.getName()); // Jane
在这个例子中,Utils
类有一个泛型方法max
,它接受两个参数并返回较大的那个参数。类型参数T
被限制为实现了Comparable
接口的类型,这样我们才能使用compareTo
方法比较它们。
下界通配符
有时我们想要传递一个参数的超类型,这可以使用下界通配符? super T
来实现。
class Box<T> {
private T value;
public Box(T value) {
this.value = value;
}
public void setValue(T value) {
this.value = value;
}
}
void setValue(Box<? super Number> box) {
box.setValue(10