1 java
虽然此代码成功编译,但它会在运行时抛出类转换异常错误:
class Test {
public static void main(String[] args) {
MyArray<String> x = new MyArray<>();
x.a[0] = "test string";
}
}
class MyArray<T> {
T[] a;
MyArray() {
this.a = (T[]) new Object[1];
}
}
Run Code Online (Sandbox Code Playgroud)
错误消息:
Exception in thread "main" java.lang.ClassCastException:
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at Test.main(Test.java:4)
Run Code Online (Sandbox Code Playgroud)
我知道的一个可能但简单的解决方案是将数组声明为Object类型的数组,然后在想要从数组中检索数组时将数组元素转换回T,如下所示:
class Test {
public static void main(String[] args) {
MyArray<String> x = new MyArray<>();
x.a[0] = "test string";
System.out.println(x.get(0));
}
}
class MyArray<T> {
Object[] a;
MyArray() {
this.a = new Object[1];
}
T get(int index) {
return (T) a[index];
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用.但是这种方法的问题在于我现在可以把任何东西放在数组中然后保持安全和声音,直到我试图将它从数组中拉出来,这将给我一个大的,胖的类转换异常错误!
MyArray<String> x = new MyArray<>();
x.a[0] = 34;
System.out.println(x.get(0)); // run-time error
Run Code Online (Sandbox Code Playgroud)
如果我们运行这段代码,这就是我们得到的:
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String
at Test.main(Test.java:5)
Run Code Online (Sandbox Code Playgroud)
显然,当所有数组元素的类型相同而不是Object类型的通用对象时,它会好得多.必须有办法做到这一点.
顺便说一下,我在这里展示的示例代码已经大大简化了.我知道我可以使用set和get方法来进行必要的类型转换,当然,这将有助于使元素完全安全地添加和获取元素进出数组.这个问题是,如果我在类中有很多其他方法也进行大量的转换,那么编写所有这些转换操作符的单调乏味会变得非常痛苦.我认为如果我可以将单词中的所有元素作为特定类型存储在单词go中,那将是非常好的.这将简化编码过程并使代码更清晰,更易于阅读.所以,任何你想要通过我的方式的智慧都是最受欢迎的,并且会非常感激.
但是这种方法的问题在于我可以在数组中放置任何东西
是.这就是你不暴露数组的原因:
class MyArray<T> {
private Object[] a;
MyArray() {
this.a = new Object[1];
}
T get(int index) {
return (T) a[index];
}
void set(int index, T value) {
a[index] = value;
}
}
Run Code Online (Sandbox Code Playgroud)
并set()防止你做错事.
由于大小为1的数组不是很有用,我在这里修改它:
class MyArray<T> {
private Object[] a;
MyArray(int size) {
this.a = new Object[size];
}
T get(int index) {
return (T) a[index];
}
void set(int index, T value) {
a[index] = value;
}
}
Run Code Online (Sandbox Code Playgroud)