'Shallow' lub 'głębokie' - i to jest kwestia, że widzę nikt definiowania precyzyjnie - metoda Arrays.copyOf(..)
robi w praktyce stworzyć kopię tablicy źródłowej, która pozostaje niezmieniona przez zmiany w tablicy źródłowej.
Weźmy następujący prosty przykład z int tablic:
import java.util.Arrays;
public class DeepCopyTest
{
public static void main(String[] args)
{
int[] source = { 1, 2, 3, 4, 5, 6};
int[] target = new int[source.length];
// Copy target from source via Arrays.copyOf(..) method :
target = Arrays.copyOf(source, 6);
// Check for equality :
System.out.println("Source1 : " + Arrays.toString(source));
System.out.println("Target1 : " + Arrays.toString(target));
// Increment all entries in source array :
for(int i = 0; i < source.length; i++)
{
source[i] = source[i] +1;
}
// See if target is affected :
System.out.println("Source2 : " + Arrays.toString(source));
System.out.println("Target2 : " + Arrays.toString(target));
}
}
// OUTPUT
// ------
Source1 : [1, 2, 3, 4, 5, 6]
Target1 : [1, 2, 3, 4, 5, 6]
Source2 : [2, 3, 4, 5, 6, 7]
Target2 : [1, 2, 3, 4, 5, 6]
W praktyce, gdy ludzie szukają „głębokie” kopię tablicy, oni po prostu chcą coś, co jest niezależne od zmian w oryginale.
Ta metoda Arrays.copyOf (..) "daje im to.
również pierwotne typu macierze, łańcuch tablice obiektów zachowywać również jak w powyższym przykładzie, dając wyjściowy jak:
Source1 : [a, b, c, d, e, f]
Target1 : [a, b, c, d, e, f]
Source2 : [a1, b1, c1, d1, e1, f1]
Target2 : [a, b, c, d, e, f]
gdy początkowe wpisów tablicy źródłem są łączone przez „1”.
Działa również dla tablic obiektów w tym sensie, że cel nie jest już powiązany ze źródłem, gdy ten drugi jest ponownie przypisywany. ale patrząc na wyjściu do pierwszego elementu obu tablicach po skopiowaniu, a następnie po zmianie źródła [0] odsłania pełną prawdę:
Source1 : [email protected]
Target1 : [email protected]
Source2 : [email protected]
Target2 : [email protected]
Po oryginalna tablica źródło jest kopiowany, elementy docelowe po prostu zostały wskazane do dowolnych wartości, które są obecnie przechowywane w ich źródłowych odpowiednikach. Dla celu [0] jest to zawartość adresu pamięci 1db9742 - który jest również tym samym źródłem podtrzymania adresu pamięci [0]. . . .
A powód otrzymujemy oddzielania między źródłem a celem po źródła [0] zmiany przypisania Wynika to z faktu, że instrukcja przypisania
source[0] = new Object();
prostu powoduje odniesienie pamięci przechowywanych w źródle [0], aby zostać zmienionym na nową lokalizację, gdy wskazywany jest nowy Obiekt. Nie jest to przecież prawdziwa głęboka kopia w czystym tego słowa znaczeniu, chociaż w wielu przypadkach daje ona koderowi te same korzyści, co głęboka kopia.
W przypadku tablic danych pierwotnych metoda Arrays.copyOf (..) nie może kopiować odniesień, ponieważ nie są one używane dla elementów pierwotnych. Po prostu kopiuje wartości elementu źródłowego do elementów docelowych. Znowu mamy ten sam efekt, co głęboka kopia kosztem operacji wymagającej znacznie mniej kodu niż w przypadku kopii głębokiej.
Array.copyOf (..) to "tania" głęboka kopia zarówno dla macierzy obiektów pierwotnych, jak i jednodomenowych. Ale jakakolwiek tablica danych jest bardziej złożona i została znaleziona.
Może powinien być nazywany pół-głęboką kopią.
Prawdopodobnie kolejne wystąpienie interlinii z ciągami – Matthias
@ Matthias: Nie sądzę. Ponieważ "Foo" jest dosłowne, zostanie internowane; testy zakładają, że. Jeśli to założenie jest poprawne, wówczas testy sprawdzają, czy element docelowy został zmieniony przez '=" Pasek "' odpowiedniego elementu źródłowego. – ToolmakerSteve
Nie widzę, gdzie testy mają jakiekolwiek założenie, czy łańcuchy są internalizowane.Nie widzę żadnych testów tożsamości, widzę tylko testy równości. Wyniki będą identyczne dla płytkich i głębokich kopii, ponieważ testy równości nie mogą się różnić między płytkimi i głębokimi kopiami. Trzeba mieć testy tożsamości, aby odróżnić płytkie i głębokie kopie. –