[英]Java Generics and Array types
遇到泛型和数组类型的问题,我无法解决。 归结为此。 在下面的代码中,如何将通用List转换为相同泛型类型的Array,同时使用工厂方法(“T convert(String value)”)转换输入通用List的每个单独元素:
@Test
public void test(){
List<String> integers = Arrays.asList("1", "2", "3", "4");
Integer[] integerArray = new TypeConverter<Integer[]>(Integer[].class).convert(integers);
assertEquals(4, integerArray.length);
assertEquals(1, integerArray[0].intValue());
assertEquals(2, integerArray[1].intValue());
assertEquals(3, integerArray[2].intValue());
assertEquals(4, integerArray[3].intValue());
}
public class TypeConverter<T>{
Class<T> type;
public TypeConverter(Class<T> type) {
this.type = type;
}
T convert(List<String> values){
List output = new ArrayList();
for (String value : values) {
//have to use Object.class here since I cant get the non-array type of T:
output.add(new TypeConverter(type.getComponentType()).convert(value));
}
return (T) output.toArray();
}
T convert(String value){
//convert to an int;
if(type == Integer.class){
return (T) new Integer(Integer.parseInt(value));
}
return null;
}
}
正如您所看到的,我的天真方法是简单地使用toArray方法,并将结果转换为:
(T) value.toArray()
但这会导致ClassCastException:
java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer
有没有办法解决这个问题,我没有看到或者我应该采取另一种方法?
编辑
这是我要修复的具体代码。 具体来说是visitArray()方法:
您可以使用List.toArray
的备用版本,该版本将您想要获取的数组类型作为参数。
您可以使用Array
类的某个方法创建一个空数组。
所以有了预期的类型,你只需使用Array.newInstance(type, 0);
并将结果传递给toArray
方法。
编辑:由于您的泛型类型是一个数组,您需要获取组件的类型,试试这个:
Object[] array = (Object[]) Array.newInstance(type.getComponentType(), 0);
return (T) output.toArray(array);
你的价值转换方法有一些东西,我会让你弄清楚如何解决:)
干杯!
不要尝试强制转换为T
,尝试强制转换为T[]
,因为您正在处理T的数组。
我建议抛弃反射和参考数组。
轻微滥用继承:
public abstract class StringConverter<T> {
public List<T> convert(List<String> values) {
List<T> output = new ArrayList<>();
for (String value : values) {
output.add(convert(value));
}
return output;
}
public abstract T convert(String value);
}
public static StringConverter<Integer> toInteger() {
return new StringConverter<>() {
public Integer convert(String value) {
return Integer.parseInt(value);
}
};
}
这对我有用:
import java.util.*;
import java.lang.reflect.*;
public class Foo {
public static void main(String[] args) {
new Foo().test();
}
public void test(){
List<String> integers = Arrays.asList("1", "2", "3", "4");
Integer[] integerArray = new TypeConverter<Integer>(Integer.class).convert(integers);
System.out.println(Arrays.deepToString(integerArray));
}
public class TypeConverter<T>{
Class<T> type;
public TypeConverter(Class<T> type) {
this.type = type;
}
T[] convert(List<String> values){
List<T> output = new ArrayList<>();
for (String value : values) {
output.add(convert(value));
}
return output.toArray((T[]) Array.newInstance(type, output.size()));
}
T convert(String value){
if(type == Integer.class){
return (T) new Integer(Integer.parseInt(value));
}
else if(type == Long.class){
return (T) new Long(Long.parseLong(value));
}
return null;
}
}
}
return (T) values.toArray();
应该是return (T)output.toArray( new Integer[0])
不,你必须硬编码new Integer[0]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.