在 Java 中使用泛型时,通常需要绑定类型参数以确保与特定类型的兼容性。 'super' 关键字可用于指定类型参数必须是指定类型的超类或超接口。但是,这种用法只能与通配符一起使用,不能与类型参数一起使用。
在 Collection 接口中,toArray 方法声明为:
<T> T[] toArray(T[] a);
此方法允许您转换集合将“T”类型的元素转换为相同类型的元素数组。但是,你不能将方法写成如下形式:
<T> <S super T> S[] toArray(S[] a);
这样做的原因是泛型中的 'super' 关键字用于绑定通配符,而不是类型参数。在上面的示例中,您尝试使用“super”将类型参数“S”绑定为“T”的超类或超接口。不允许这种用法,因为它可能会导致类型安全问题。
例如,考虑以下代码:
List<Integer> integerList = new ArrayList<>(); Integer[] integerArray = new Integer[5]; Number[] numberArray = new Number[5]; Object[] objectArray = new Object[5]; // hypothetical method integerList.toArray(super T numberArray)
根据您建议的语法,上述代码将允许以下类型分配:
integerList.toArray(super T integerArray) // compiles fine! integerList.toArray(super T numberArray) // compiles fine! integerList.toArray(super T objectArray) // compiles fine!
但是,由于 'String' 不是 'Integer' 的超类,因此以下代码不应编译:
integerList.toArray(super T stringArray) // should not compile
但是,由于 'Object ' 是 'Integer' 和 'String' 的超类,以下代码仍然会编译,即使它会在运行时抛出 'ArrayStoreException':
integerList.toArray(super T stringArray) // compiles fine!
这种行为是不可取的,因为它可能会导致键入安全违规行为。为了防止这种情况,Java 不允许使用“super”来绑定类型参数。相反,您只能使用 'super' 来绑定通配符。
例如,您可以使用通配符重写 toArray 方法,如下所示:
<T> T[] toArray(T[] a);
此方法允许您编写代码这既是类型安全的又是灵活的。例如,以下代码编译并且在运行时不会抛出“ArrayStoreException”:
List<Integer> integerList = new ArrayList<>(); Integer[] integerArray = new Integer[5]; Number[] numberArray = new Number[5]; Object[] objectArray = new Object[5]; integerList.toArray(objectArray);
以上是为什么我们不能在 Java 中将泛型类型参数与“super”绑定?的详细内容。更多信息请关注PHP中文网其他相关文章!