面试题答案
一键面试处理泛型类型参数的边界
- 上界:使用
extends
关键字来限制类型参数必须是某个类或接口的子类或实现类。例如,若希望自定义的List
只能存储Number
及其子类的对象,可以这样定义泛型参数:class MyList<T extends Number>
。这确保了在这个MyList
中只能添加Number
及其子类(如Integer
、Double
等)的实例。 - 下界:使用
super
关键字来限制类型参数必须是某个类或接口的超类。例如,class MyList<T super Integer>
表示T
必须是Integer
或Integer
的超类,这样在添加元素时,只要是Integer
类型或其子类类型的元素都可以添加进来。
保证类型安全
- 使用泛型检查:Java 的泛型在编译时进行类型检查,确保类型的正确性。例如,定义
MyList<Integer>
后,尝试添加非Integer
类型的元素会在编译时报错。 - 避免类型转换错误:通过泛型,在获取元素时无需进行强制类型转换,减少了
ClassCastException
的风险。例如,从MyList<Integer>
中获取元素时,编译器已经知道元素类型是Integer
,无需手动转换。
处理不同类型数据的存储和读取
- 存储:在定义泛型类型参数后,存储元素时确保添加的元素类型与泛型类型参数一致。例如,
MyList<String>
只能添加String
类型的元素。 - 读取:读取元素时,由于泛型已经指定了类型,无需进行类型转换。例如,从
MyList<Integer>
中读取元素时,直接得到Integer
类型的对象。
关键代码示例
import java.util.Arrays;
public class MyList<T> {
private Object[] elements;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyList() {
elements = new Object[DEFAULT_CAPACITY];
size = 0;
}
public void add(T element) {
ensureCapacity();
elements[size++] = element;
}
@SuppressWarnings("unchecked")
public T get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
return (T) elements[index];
}
private void ensureCapacity() {
if (size == elements.length) {
elements = Arrays.copyOf(elements, elements.length * 2);
}
}
public int size() {
return size;
}
}
以下是测试代码:
public class Main {
public static void main(String[] args) {
MyList<Integer> myList = new MyList<>();
myList.add(1);
myList.add(2);
Integer num = myList.get(0);
System.out.println(num);
}
}