"not applicable for the arguments ..." issue when creating Java generics arrays, e.g., `T[]`, as both input and output of a method

Viewed 31

I am newbie to Java and now learning the Java generics. I encountered a issue when I tried to build a method with both input and output arguments of the generics type T[].

Example


Assuming we have a method f which aims to fetch the first n entries of an array arr. If the array consists of integers, we can implement it as below for example:

    public static int[] funcInt(int[] arr, int n) {
        int[] res = new int[n];
        int i = 0;
        while (i < n) {
            res[i] = arr[i];
            i++;
        }
        return res;
    }

Then, I am wondering whether we can step further by using T[] instead of int[] for the array arr, such that this method applies to arrays of other types. My attempt is below:

    public static <T> T[] Func(T[] arr, int n) {
        T[] res = (T[]) Array.newInstance(arr.getClass(), n);
        int i = 0;
        while (i < n) {
            res[i] = arr[i];
            i++;
        }
        return res;
    }

However, given an integer array int[] a = { 1, 2, 3, 5, 7, 8, 3 };:

  • If I run funcInt, e.g., System.out.println(Arrays.toString(funcInt(a, 3)));, I can achieve the desired output
Note: test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
[1, 2, 3]
  • If I run Func, e.g., System.out.println(Arrays.toString(Func(a, 3))), errors pop up as below
test.java:36: error: method Func in class test cannot be applied to given types;
        System.out.println(Arrays.toString(Func(a, 3)));
                                           ^
  required: T[],int
  found:    int[],int
  reason: inference variable T has incompatible bounds
    equality constraints: int
    lower bounds: Object
  where T is a type-variable:
    T extends Object declared in method <T>Func(T[],int)
Note: test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Question

I have no clue what's wrong in my Func method with T[] and why is the error

method Func in class test cannot be applied to given types

Could anyone explain a bit and correct me if I had misused T[] somewhere? Much appreciated!

1 Answers

3 issues:

  1. An int can't really be generified, use Integer instead
  2. You're using arr.getClass(), which will return the array type for T. Instead, use arr.getClass().getComponentType(), which will return T.
  3. You're doing i++ in the res[i++] = arr[i] part, which is equivalent to res[i] = arr[i+1], and will shift all elements to the left once.

Here's a corrected solution:

public static <T> T[] Func(T[] arr, int n) {
    T[] res = (T[]) Array.newInstance(arr.getClass().componentType(), n);
    int i = 0;
    while (i < n) {
        res[i] = arr[i++];
    }
    return res;
}
Related