Спеку не ковырял на предмет объяснения, почему происходит именно так, а не иначе, но само знание о таком моменте может пригодиться.
В следующем примере (1) компилится (с последующим ArrayStoreException в рантайм), (2) не компилится:
public class BBB {
public static void main(String[] args) throws Exception {
String[] array = new String[1];
store(array, 1); // (1)
Collection<String> collection = new ArrayList<String>();
store(collection, 2); // (2)
}
private static <T> void store(T[] array, T element) {
array[0] = element;
}
private static <T> void store(Collection<T> collection, T element) {
collection.add(element);
}
}
Лечится:
вариант 1
public class BBB {
public static void main(String[] args) throws Exception {
String[] array = new String[1];
BBB.<String>store(array, 1);
}
private static <T> void store(T[] array, T element) {
array[0] = element;
}
}
вариант 2
public class BBB {
public static void main(String[] args) throws Exception {
String[] array = new String[1];
store(array, 1);
}
private static <T, S extends T> void store(T[] array, S element) {
array[0] = element;
}
}
Здравствуйте, bolshik, Вы писали:
B>В следующем примере (1) компилится (с последующим ArrayStoreException в рантайм), (2) не компилится:
public static void main(String[] args) throws Exception {
String[] array = new String[1];
store(array, 1); // (1)
Collection<String> collection = new ArrayList<String>();
store(collection, 2); // (2)
}
private static <T> void store(T[] array, T element) {
array[0] = element;
}
Подозреваю что в методе просто нет информайции о типе T. Поэтому он Object. Мне кажется что эта информация берется только из Generic классов. Коим массив не является. А вот коллекция — является.
Здравствуйте, Blazkowicz, Вы писали:
B>Подозреваю что в методе просто нет информайции о типе T. Поэтому он Object. Мне кажется что эта информация берется только из Generic классов. Коим массив не является. А вот коллекция — является.
Может, и так, хотя можно рассмотреть другую ситуацию: массив явно не имплементит Iterable, но компилятор генерит нужные инструкции при использовании его в foreach. Поэтому кажется логичным, что в случае с дженериками со стороны компилятора тоже должна быть осуществлена необходимая поддержка массивов, но этого не происходит.
В общем, надо лезть в спеку за объяснением
Здравствуйте, bolshik, Вы писали:
B>Может, и так, хотя можно рассмотреть другую ситуацию: массив явно не имплементит Iterable, но компилятор генерит нужные инструкции при использовании его в foreach. Поэтому кажется логичным, что в случае с дженериками со стороны компилятора тоже должна быть осуществлена необходимая поддержка массивов, но этого не происходит.
На счет Iterable. Нигде не сказано что массив должен его реализовывать. Зато сказано что foreach перебирает Iterable и массивы.
Хотя это точно такая же недоработка.
Кстати по твоей наводке про Iterable нашлась
бага, которая, вероятно, и проблему с генериками покрывает так же.
Здравствуйте, Blazkowicz, Вы писали:
B>На счет Iterable. Нигде не сказано что массив должен его реализовывать. Зато сказано что foreach перебирает Iterable и массивы.
B>Хотя это точно такая же недоработка.
B>Кстати по твоей наводке про Iterable нашлась бага, которая, вероятно, и проблему с генериками покрывает так же.