Not in this particular case.
The general array T[] is erased to Object[] in bytecode. The array aggregator for Object[] always returns Object , so it does not need to check the actual type of the array. Therefore, there is no use in using T[] instead of Object[] for the operation of getting the array. In both cases, there is an aaload instruction followed by a checkcast , and it works the same way.
At the same time, if the array parameter is worse for a typed array, rather than Object[] , because aastore should check if the value matches the actual type of the array component.
That is, the proposed modification works equally for get , but performs worse for set . This can be confirmed using the following JMH test.
package bench; import org.openjdk.jmh.annotations.*; import java.lang.reflect.Array; @State(Scope.Benchmark) public class Generics { private ObjectArray<String> objectArray; private GenericArray<String> genericArray; private StringArray stringArray; private int index; @Param("100000") private int length; @Setup public void setup() { genericArray = new GenericArray<>(String.class, length); objectArray = new ObjectArray<>(length); stringArray = new StringArray(length); for (int i = 0; i < length; i++) { String s = Integer.toString(i); objectArray.set(i, s); genericArray.set(i, s); stringArray.set(i, s); } } @Benchmark public String getGenericArray() { return genericArray.get(nextIndex()); } @Benchmark public String getObjectArray() { return objectArray.get(nextIndex()); } @Benchmark public String getStringArray() { return stringArray.get(nextIndex()); } @Benchmark public void setGenericArray() { genericArray.set(nextIndex(), "value"); } @Benchmark public void setObjectArray() { objectArray.set(nextIndex(), "value"); } @Benchmark public void setStringArray() { stringArray.set(nextIndex(), "value"); } private int nextIndex() { if (++index == length) index = 0; return index; } static class GenericArray<T> { private T[] data; @SuppressWarnings("unchecked") public GenericArray(Class<T> type, int length) { this.data = (T[]) Array.newInstance(type, length); } public T get(int index) { return data[index]; } public void set(int index, T value) { data[index] = value; } } static class ObjectArray<T> { private Object[] data; public ObjectArray(int length) { this.data = new Object[length]; } @SuppressWarnings("unchecked") public T get(int index) { return (T) data[index]; } public void set(int index, T value) { data[index] = value; } } static class StringArray { private String[] data; public StringArray(int length) { this.data = new String[length]; } public String get(int index) { return data[index]; } public void set(int index, String value) { data[index] = value; } } }
And the results:
Benchmark (length) Mode Cnt Score Error Units Generics.getGenericArray 100000 avgt 40 5,212 ± 0,038 ns/op <- equal Generics.getObjectArray 100000 avgt 40 5,224 ± 0,043 ns/op <- Generics.getStringArray 100000 avgt 40 4,557 ± 0,051 ns/op Generics.setGenericArray 100000 avgt 40 3,299 ± 0,032 ns/op <- worse Generics.setObjectArray 100000 avgt 40 2,456 ± 0,007 ns/op <- Generics.setStringArray 100000 avgt 40 2,138 ± 0,008 ns/op