簡體   English   中英

Java泛型和數組類型

[英]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()方法:

https://github.com/johncarl81/transfuse/blob/master/transfuse/src/main/java/org/androidtransfuse/analysis/adapter/AnnotationTypeValueConverterVisitor.java

您可以使用List.toArray的備用版本,該版本將您想要獲取的數組類型作為參數。

toArray方法

您可以使用Array類的某個方法創建一個空數組。

Array.newInstance

所以有了預期的類型,你只需使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM