0

I cannot correctly write the generic method for this:

private int [] loadIntArray(String key, int [] defaultArray) {
    int [] array = new int [4];
    for( int index=0; index<4 ; index++) {
        array[index] = sp.getInt(key + index, defaultArray[index]);
    }
    return array;
}

I wrote this:

private <T[]> loadArray(String key, <T[]> defaultArray) {
    <T[]> array = new <T[LEVELS]>;
    for( int index=0; index<4 ; index++) {
        array[index] = sp.getInt(key + index, defaultArray[index]);
    }
    return array;
}

But it does not compile.
I get several errors, "Return type for method is missing", "Type expected after private token".

What would be the right way to write it?

5 Answers 5

3

In order to achieve that you must add a class parameter to your method

Class<T> type

your method look now as follow

 private <T> T[] loadArray(Class<T> type, String key, T[] defaultArray) {
      T[] array = (T[]) Array.newInstance(type, defaultArray.length);
      for (int index = 0; index < array.length; index++) {
         array[index] = sp.getInt(key + index, defaultArray[index]);
      }
      return array;
   }

Update after the question:
How would a call to this method look like? (for example for type "int")?

When creating a Pair object, you cannot substitute a primitive type for the type parameter K or V:

Pair<int, char> p = new Pair<>(8, 'a'); // compile-time error You can substitute only non-primitive types for the type parameters K and V:

Pair<Integer, Character> p = new Pair<>(8, 'a');

A possible workaround
(The only way to pass it in a generic manner and keep it as a primitive array is as an Object.)

Object a[]= {1,2,3};
loadArray(Object.class, "test", a);

Or you can use a non primitiv type (Integer)

Integer a[]= {1,2,3};
loadArray(Integer.class, "test", a);
Sign up to request clarification or add additional context in comments.

2 Comments

How would a call to this method look like? (for example for type "int"
The only way to pass it in a generic manner and keep it as a primitive array is as an Object.
2

You'll return an array of type T, not a certain type T[].

This will be more in the direction you want to go.

private <T> T[] loadIntArray(String key, T[] defaultArray) {
    T[] array = new T[4]; // Need more info to correct this
    for (int index = 0; index < 4; index++) {
        array[index] = sp.getInt(key + index, defaultArray[index]);
    }
    return array;
}

2 Comments

Almost perfect! The new T[4] still does not compile "Cannot create a generic array of T"
1

Assuming defaultArray will always be nil and will always be an array of the component type T, you can use its type to construct the new array:

import java.lang.reflect.Array;

private <T> T[] loadIntArray(String key, T[] defaultArray) {
    T[] array = (T[])Array.newInstance(defaultArray.getClass().getComponentType(), 4);
    for (int index = 0; index < 4; index++) {
        array[index] = sp.getInt(key + index, defaultArray[index]);
    }
    return array;
}

Note that however, if the defaultArray's runtime type is an array of some subtype of T, this won't work. It will cause an ArrayStoreException.

Comments

0

To start with, the method signature should look like this:

private <T> T[] loadArray(String key, T[] defaultArray)

Comments

0

This the OP.
Although this is not the marked answer I wanted to post the final code that compiles for the sake of those who want to see it.

One important thing that was not mentioned in other answers is that Java generics do not support primitve types (int, float, ...) only objects. So I had to change my arrays to be of Integer and Float instead.

private <T> void loadArray(final T[] array, final String key, final T[] defaultArray) {
    int count = array.length;
    for( int index = 0; index < count; index++ ) {
        //if( array[index] instanceof PointF ) {
        if( array instanceof PointF[] ) {
            PointF element = new PointF();
            element.x = sp.getFloat(key + index, (Float) defaultArray[index]);
            element.y = sp.getFloat(key + index, (Float) defaultArray[index]);
            array[index] = (T) element;
        //} else if( array[index] instanceof Float ) {
        } else if( array instanceof Float[] ) {
            Float element = sp.getFloat(key + index, (Float) defaultArray[index]);
            array[index] = (T) element;
        //} else if( array[index] instanceof Integer ) {
        } else if( array instanceof Integer[] ) {
            Integer element = sp.getInt(key + index, (Integer) defaultArray[index]);
            array[index] = (T) element;
        }
    }
}

Edit
It turns out that if the array is dimensioned, but not initialized,

array[index] instanceof Integer  

returns false, so I changed the test to

arrray instanceof Integer[]  

which returns true even if the array elements are null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.