System.arraycopy не хвърля ArrayIndexOutOfBoundsException

Не разбирам точно как работи System.arraycopy. Имайте прост пример:

String[] arr = {"a"};
String[] copyArr = new String[10];
System.arraycopy(arr, 0, copyArr, 0, 1);
System.out.println(Arrays.toString(copy));

Разбирам го като „копиране на 1 елемент от arr, започващ от [0], до copyArr до позиция [0]“. И това е добре. Сега го променям на:

String[] arr = {"a"};
String[] copyArr = new String[10];
System.arraycopy(arr, 1, copyArr, 0, 0);
System.out.println(Arrays.toString(copy));

Тъй като arr.length е 1 и единственият индекс, който можем да извикаме, е [0], очаквах, че ще изхвърли ArrayIndexOutOfBoundsException, но не го прави.

Така че въпросът е каква е разликата между тези два реда по-долу и защо първият е възможен, ако няма елемент в [1] в src (защото дължината му е 1), това е естествен метод, така че как се прилага вътрешно?

System.arraycopy(src, 1, dest, 0, 0);
System.arraycopy(src, 0, dest, 0, 0);

Какво е интересно, когато го променим на:

System.arraycopy(src, 2, dest, 0, 0);

има ArrayIndexOutOfBoundsException (и този случай е описан в документите, защото srcPos+length > src.length).


person swch    schedule 03.11.2016    source източник
comment
Защото това пише в документацията? Или искате да знаете защо пише това?   -  person Tunaki    schedule 03.11.2016


Отговори (2)


Има масив с нулева дължина в src[1], който можете да "копирате". Няма масив с нулева дължина в src[2], така че изключението се хвърля.

Представете си масив с размер 3 и подмасивите, които съдържа (показани са размерите на подмасивите):

[ 0 ][ 1 ][ 2 ]
[ -----3------]
     [----2---]
          [-1-]
             []

Същото за началото на масива и всяка позиция между индексите.

person Kayaman    schedule 03.11.2016
comment
би било чудесно, ако можете да развиете малко отговора си - person sanbhat; 03.11.2016
comment
Благодаря, бих добавил само, че в изпълнението на arraycopy има фрагмент от код, който изглежда така if (length==0) { return; } и може да бъде намерен в въпрос, свързан от @FaigB и показва как се прилага вътрешно - person swch; 03.11.2016

Ето ви тема

от кода е ясно:

// Check if the ranges are valid
if  ( (((unsigned int) length + (unsigned int) src_pos) > (unsigned int) s->length())
   || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) )   {
  THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
}
person FaigB    schedule 03.11.2016