0

I am unable to provide values of type int[], float[], etc. to a generic function. I get errors that say basically that float[] is the wrong type and Float[] is what the function actually takes.

Here's an example of a method I wrote, and I'm trying to give it values like new int[]{0,1} (created in library somewhere else).

private static <T> JSONArray encodeArray(T[] array) {
    JSONArray arr = new JSONArray();
    Collections.addAll(arr, array);
    return arr;
}

Is it even possible to write my function signature to accept these arrays of literals?

I could go to the call site, and do a conversion of float[] to Float[], but I don't know how to do that either.

Kevin Beal
  • 10,500
  • 12
  • 66
  • 92
  • Conversion from `float[]` to `Float[]` seems pretty straightforward to me using a simple for loop. – jrook Oct 19 '20 at 17:54
  • 1
    @jrook It's not straightforward to me. I am just learning Java and the instance of `new Float[]` has no `.add()` or `.push()` methods. – Kevin Beal Oct 19 '20 at 17:59
  • I believe something like `for(int i = 0; i < n; i++) {y[i] = x[i];}` should work (`x:float[]` and `y:Float[]`. The function then can accept `y`. – jrook Oct 19 '20 at 18:02
  • This could solve your problem [enter link description here](https://stackoverflow.com/questions/880581/how-to-convert-int-to-integer-in-java) – vincendep Oct 19 '20 at 18:29
  • A very interesting read wrt. primitive generics: https://cr.openjdk.java.net/~briangoetz/valhalla/erasure.html – Polygnome Oct 19 '20 at 18:38

3 Answers3

0

The method which accepts a generic array.

public <T> void printArray(T[] array){
        for (T element: array){
            System.out.println(element);
        }
    }

You can't use primitives in generic functions. When generic are compiled, you end up with Object[] in the above example as the implementing type. As int[] and byte[] etc, do not extend Object[] you cannot use them interchangeably even if the code involved would be identical (again generics are not templates)

0

Add on the solution from @Max-Reshetnyk, It is better if you check ArrayList for methods that help you add or remove... elements. Since primitive types are not meant to be used with generics, you should AutoBox them with their respective types and then use generics.

For instance:

class Main {
  public static void main(String[] args) {
    Integer[] x = new Integer[1];
    x[0] = 1;
    printArray(x); 
  }

  public static <T>  void printArray(T[] array){
        for (T element: array){
            System.out.println(element);
        }
    }
}
Aman
  • 1,627
  • 13
  • 19
0

Is it even possible to write my function signature to accept these arrays of literals?

It is possible, but the parameter type will have to be Object, because that is the only common superclass of "arrays of primitives" and "arrays of references" (e.g. it can't be Object[] since arrays of primitives are not subclasses of Object[]). (There are also some interfaces that all arrays implement, but I will ignore those for now.) Unfortunately, this means that you will lose type safety as the compiler will not be able to give an error at compile time if someone passes a non-array type in.

To do array operations on this Object value, you will need to use the methods in the reflection helper class java.lang.reflect.Array. So you can do something like this:

import java.lang.reflect.Array;

// ...

private static JSONArray encodeArray(Object array) {
    JSONArray arr = new JSONArray();
    for (int i = 0, n = Array.getLength(array); i < n; i++) {
        arr.add(Array.get(array, i)); // primitives are automatically wrapped
    }
    return arr;
}
newacct
  • 119,665
  • 29
  • 163
  • 224