Специализация кода. Компилятор генерирует новое представление для
каждого экземпляра универсального типа или метода. Например,
компилятор будет генерировать код для списка целых чисел и дополнительный
другой код для списка строк, списка дат, списка
буферов и так далее.
Совместное использование кода. Компилятор генерирует код только для одного представления
универсального типа или метода и сопоставляет все экземпляры
универсального типа или метода с уникальным представлением, выполняя
проверки типов и преобразования типов, где это необходимо. .
В Java используется метод совместного использования кода. Я считаю, что C# следует методу специализации кода, поэтому, по моему мнению, весь приведенный ниже код является логичным, используя C#.
Предполагая, что этот фрагмент кода Java:
Код: Выделить всё
public class Test {
public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
//5 as static size for the sample...
return (T[]) Arrays.copyOf(a, 5, a.getClass());
}
}
Код: Выделить всё
public class Test {
public static void main(String[] args) {
Test t = new Test();
//Notice the cast added by the compiler here
String[] newArray = (String[])t.toArray(new String[4]);
}
@SuppressWarnings("unchecked")
public Object[] toArray(Object[] a) {
//5 as static size for the sample...
return Arrays.copyOf(a, 5, a.getClass());
}
}
Какова необходимость уточнить этот первоначальный состав? :
Код: Выделить всё
(T[]) Arrays.copyOf(a, 5, a.getClass());
Код: Выделить всё
Arrays.copyOf(a, 5, a.getClass());
Хорошо, Arrays.copyOf возвращает Object [] и на них нельзя напрямую ссылаться более конкретным типом без явного приведения к понижению.
Но не может ли компилятор приложить усилия в этом случае, поскольку он имеет дело с обобщенным типом (возвращаемым типом!)?
Действительно, разве не достаточно того, что компиляторы применяют явное приведение к строке вызова метода? :
Код: Выделить всё
(String[])t.toArray(new String[4]);
Спасибо @ruakh за ответ.
Вот пример, который доказывает, что явное приведение, даже просто присутствующее во время компиляции, актуально:
Код: Выделить всё
public static void main(String[] args) {
Test t = new Test();
String[] newArray = t.toArray(new String[4]);
}
public T[] toArray(T[] a) {
return (T[]) Arrays.copyOf(a, 5, Object[].class);
}
Итак, если говорить о том, что «недостаточно того, что компиляторы применяют явное приведение к строке вызова метода», то ответ такой:
Разработчик не справляется с этим приведением, поскольку оно создается автоматически на этапе компиляции, поэтому эта функция времени выполнения не предупреждает пользователя о необходимости тщательно проверить свой код на предмет его безопасности ПЕРЕД запуском компиляции.
Короче говоря, этот актерский состав достоин внимания.
Подробнее здесь: https://stackoverflow.com/questions/136 ... h-generics