这是一个让我几乎失去所有希望的难题。我正在尝试编写一个函数,但是在获取 ArrayList.toArray()
返回我所需类型方面遇到了问题。
下面是一个最简示例,展示了我的问题:
public static <T> T[] test(T one, T two) {
java.util.List<T> list = new ArrayList<T>();
list.add(one);
list.add(two);
return (T[]) list.toArray();
}
通常情况下,我可以使用这个表单 (T[]) list.toArray(new T[0])
,但是出现了两个额外的困难:
- 由于协变规则,我不能类型转换数组,
(T[]) myObjectArray
会抛出ClassCastException
- 您无法创建泛型类型的新实例,这意味着我不能实例化
new T[]
。我也不能在ArrayList
的一个元素上使用 clone 或尝试获取其类。
我一直在尝试使用以下调用获取一些信息:
public static void main(String[] args) {
System.out.println(test("onestring", "twostrings"));
}
结果的形式为 [Ljava.lang.Object; @ 3e25a5
,表明返回值的强制类型转换无效。奇怪的是下面的代码:
public static void main(String[] args) {
System.out.println(test("onestring", "twostrings").getClass());
}
返回结果如下:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at patchLinker.Utilities.main(Utilities.java:286)
所以我的最佳猜测是它认为它是一个字符串数组标签,但在内部是一个对象数组,任何尝试访问都会引发这种不一致性。如果有人能找到任何解决方法(因为两个常规解决方法被拒绝了),我将非常感激。
K.Barad JDK1.6
编辑
感谢Peter Lawrey解决了最初的问题。现在的问题是如何使解决方案适用于我更不平凡的例子:
public static <T> T[] unTreeArray(T[][] input) {
java.util.List<T> outList = new ArrayList<T>();
java.util.List<T> tempList;
T[] typeVar;
for (T[] subArray : input) {
tempList = java.util.Arrays.asList(subArray);
outList.addAll(tempList);
}
if (input.length > 0) {
typeVar = input[0];
} else {
return null;
}
return (T[]) outList.toArray((T[]) java.lang.reflect.Array.newInstance(typeVar.getClass(),outList.size()));
}
public static void main(String[] args) {
String[][] lines = { { "111", "122", "133" }, { "211", "222", "233" } };
unTreeArray(lines);
}
目前的结果是:
Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at java.util.ArrayList.toArray(Unknown Source)
at patchLinker.Utilities.unTreeArray(Utilities.java:159)
at patchLinker.Utilities.main(Utilities.java:301)
我正在进行一些测试,以查看是否可以获得比这更有用的信息,但目前我不确定从哪里开始。 我会在获取更多信息时添加任何更多的信息。
K.Barad
编辑2
现在有更多信息了。 我尝试手动构建数组并逐个元素地传输项目,因此我将其强制转换为T,而不是T []。 我发现了一个有趣的结果:
public static <T> T[] unTreeArray(T[][] input) {
java.util.List<T> outList = new ArrayList<T>();
java.util.List<T> tempList;
T[] outArray;
for (T[] subArray : input) {
tempList = java.util.Arrays.asList(subArray);
outList.addAll(tempList);
}
if (outList.size() == 0) {
return null;
} else {
outArray = input[0];// use as a class sampler
outArray =
(T[]) java.lang.reflect.Array.newInstance(outArray.getClass(), outList.size());
for (int i = 0; i < outList.size(); i++) {
System.out.println(i + " " + outArray.length + " " + outList.size() + " " + outList.get(i));
outArray[i] = (T) outList.get(i);
}
System.out.println(outArray.length);
return outArray;
}
}
我仍然得到以下输出:
0 6 6 111
Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
at patchLinker.Utilities.unTreeArray(Utilities.java:291)
at patchLinker.Utilities.main(Utilities.java:307)
这是否意味着即使您间接创建了一个T[]
,也无法对其进行写入操作?