Search code examples
javaarraysgenericsprimitive

passing primitive int array class (int[].class) to a generic method which expects Class<T[]> fails to compile


I have following code:

public class Test {

    private Map<String, Object> delegate;

    public Test(Map<String, Object> delegate) {
        this.delegate = delegate;
    }

    public <T> T[] getValueAsArray(String key, Class<T[]> arrayClz) {
        T[] ret = null;
        Object val = delegate.get(key);
        if (val != null && arrayClz != null && arrayClz.isInstance(val)) {
            ret = (T[]) val;
        }
        return ret;
    }

    public static void main(String[] args) {
        Map<String, Object> delegate = new HashMap<>();
        int[] intArray = new int[3];
        intArray[0] = 1;
        intArray[1] = 2;
        intArray[2] = 3;
        delegate.put("intArray", intArray);

        Integer[] integerArray = new Integer[3];
        integerArray[0] = 1;
        integerArray[1] = 2;
        integerArray[2] = 3;
        delegate.put("integerArray", integerArray);

        Test test = new Test(delegate);
        //int[] a = test.getValueAsArray("intArray", int[].class);
        //System.out.println(Arrays.toString(a));
        Integer[] b = test.getValueAsArray("integerArray", Integer[].class);
        System.out.println(Arrays.toString(b));
    }

}

If I uncomment the following code from the above class, it does not compile.

    //int[] a = test.getValueAsArray("intArray", int[].class);
    //System.out.println(Arrays.toString(a));

It gives the following error:

Error:(44, 31) java: method getValueAsArray in class com.jpmorgan.cu.collections.Test cannot be applied to given types;
  required: java.lang.String,java.lang.Class<T[]>
  found: java.lang.String,java.lang.Class<int[]>
  reason: inferred type does not conform to declared bound(s)
    inferred: int
    bound(s): java.lang.Object

Can someone explain why does this not work? I was under assumption that array is Object, so int[] and Integer[] are different but both are Objects. What is the best way to make this method work for primitive arrays as well as object arrays?


Solution

  • int[] is a reference type. Integer[] is a reference type. int is a primitive type. Integer is a reference type.

    T[] describes an array type where the component type is the generic type T, to be bound at some point.

    If you call

    Integer[] b = test.getValueAsArray("integerArray", Integer[].class);
    

    you're trying to bind Integer to T. That will work since Integer is a reference type, which can be used with the unbounded generic type variable T.

    But if you call

    test.getValueAsArray("integerArray", int[].class);
    

    you are trying to bind int to T. This will not work because generic types only work with reference types and int is a primitive type.