java trim泛型数组
可能重复:java trim泛型数组,java,generics,casting,Java,Generics,Casting,可能重复: 我想将一个通用的对象数组裁剪为仅第一个len元素。这似乎应该奏效: @SuppressWarnings("unchecked") public static <T> T[] trimArray(T[] data, int len){ T[] result = (T[]) new Object[len]; System.arraycopy(data, 0, result, 0, len); return result; } 我不明白为什么这样做行
我想将一个通用的对象数组裁剪为仅第一个len元素。这似乎应该奏效:
@SuppressWarnings("unchecked")
public static <T> T[] trimArray(T[] data, int len){
T[] result = (T[]) new Object[len];
System.arraycopy(data, 0, result, 0, len);
return result;
}
我不明白为什么这样做行不通,但类似的事情在JDK中已经有了一个内置的:
Foo[] B = Arrays.copyOf(A, 3);
(自1.6起)
但是请注意,如果源数组长度小于所需的长度,它也会扩展数组(用null
s填充)。您可以通过以下方式轻松解决此问题,例如:
Foo[] B = Arrays.copyOf(A, Math.min(3, A.length));
发生这种情况是因为数组是协变的,这意味着您可以将子类型的数组视为超类型的数组,但事实并非如此 尽管这是一个难看的破解,但您可以做的是根据需要返回一个
对象[]
,然后将每个元素强制转换为T
(数组中的实际元素是协变的,但数组本身不是),但我强烈建议不要这样做
使用其他答案中推荐的内置选项,如Arrays.copyOf
如果您想知道为什么,那是因为这太容易破坏类型安全性
例如:
Object[] bla = new Object[10];
bla[0] = new Integer(2);
bla[1] = "stillanObject";
您有一个对象数组,完全有效
现在,您将其转换为,比方说,一个字符串数组
return (String[])bla;
地狱将在JVM上释放,实际上您将拥有一个类型为String
的数组,其中包含String
和Integer
对象\
类型安全是一件好事
更新:
只需再添加一个详细信息,您可以将
字符串[]
强制转换为对象[]
,但如果您尝试存储任何非字符串(或原始数组类型)的内容,则这可能会在阵列存储异常中发生。将原始数组作为Object[]
读取是完全安全的。发布完整的堆栈跟踪。Foo[]
数组与Object[]
数组不同:您可以在第二个数组中存储任何您想要的内容,而只能在第一个数组中存储Foo实例。From WP:“协变:从专用类型转换(猫)到更一般的类型(动物):每只猫都是动物。“现在,你从更一般的(对象)转换到更特殊的(字符串)。并称之为协变。你确定吗?你是对的,我在那里切换了术语,应该是固定的。
return (String[])bla;