В чём преимущество (T[]) Array.newInstance(newType.getComponentType(), newLength) перед (T[]) new Object[newLength]?
Если посмотреть в реализацию метода Arrays.copyOf java, то там мы увидим следующий код
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
За счёт стирания типов, мы всё равно получим Object, так для чего тогда Array.newInstance(newType.getComponentType(), newLength) ?
Ответы (1 шт):
Автор решения: Alexandr
→ Ссылка
Советую Вам почитать про Ковариантность и контравариантность.
Вы приводите только выдержку. Необязательно будет создан Object[], все зависит от параметра newType:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
Для информации приведу небольшой тест (Jdk11+), в котором будет использоваться именно Array.newInstance(newType.getComponentType(), newLength):
package com.somepackage;
import lombok.Data;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
public class ArraysCopyOfTest {
@Data
static class Shape { }
@Data
static class Circle extends Shape { }
@Data
static class Triangle extends Shape { }
@Test
public void test_throws() {
assertThrows(
ArrayStoreException.class,
() -> {
Circle[] circles =
new Circle[]{
new Circle(),
new Circle()
};
Shape[] shapes = circles;
shapes[0] = new Triangle();
});
}
@Test
public void test_doesNotThrow() {
assertDoesNotThrow(
() -> {
Circle[] circles =
new Circle[]{
new Circle(),
new Circle()
};
Shape[] shapes =
Arrays.copyOf(
circles, circles.length, Shape[].class);
shapes[0] = new Triangle();
});
}
@Test
public void test_class() {
Circle[] circles =
new Circle[]{
new Circle(),
new Circle()
};
assertEquals(
Shape[].class,
Arrays.copyOf(
circles, circles.length, Shape[].class
).getClass());
}
}