2012-09-24 12 views
7

Ludzie,Java - Clone właściwość wewnątrz metody pochłaniacza

ja jechałem przez najlepszych praktyk kodowania Javy wymienionych tutaj
http://viralpatel.net/blogs/most-useful-java-best-practice-quotes-java-developers/

2-ty cytat mówi

Cytat 2: Nigdy nie dokona przykładowe pola klasy publicznej

Zgadzam się, że to absolutnie poprawne, ale utknąłem za zaleceniem pisarza kilka linii poniżej tego cytatu.

Mówi


private String[] weekdays = 
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() { 
    return weekdays; 
} 

Ale pisząc metodę getter nie dokładnie rozwiązać nasz problem. Tablica jest nadal dostępna. Najlepszym sposobem uczynienia go niezmodyfikowanym jest zwrócenie klona tablicy zamiast samej tablicy. Zatem metoda getter zostanie zmieniony na

public String[] getWeekdays() { 
    return weekdays.clone(); 
} 

nigdy nie używane clone() się wewnątrz każdej metody pochłaniacza klasy Javy.

Zastanawiam (jak jest ona wymieniona jako jedna z dobrych praktyk) - dlaczego jeden should use/shouldn't useclone() wewnątrz metody getter? i w jakich scenariuszach?

Czy to może być dobra praktyka kodowania dla Javy?

Dzięki

+2

IMO - Dla obiektów niezmiennych i typów danych pierwotnych klon nie jest wymagany. Jeśli chcemy, aby nasze dane były bezpieczne, musimy zwrócić kopię klonu, a nie oryginał. –

+2

Możesz zwrócić 'Arrays.asList (daysdays)', który będzie niezmienny. – Jivings

+2

@Jivings not true. Lista nie przyjmuje nowych elementów, ale metody set() działają. –

Odpowiedz

3
private String[] weekdays =  
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() 
{  
    return weekdays; 
} 

Jeśli nie używać clone metodę, użytkownik tej klasy mogą zrobić wiele nieetycznych rzeczy:

  1. zmienić kolejność dni,
  2. zmiany nazwa dni,
  3. ...

Ale powrót klona nie wpłynie na klasę i jej dane. Tak więc nie wpłynie to na innych użytkowników klasy.

+0

Ale nie widziałem tego zalecenia metody clone() na żadnej stronie wcześniej. Nie widziałem większości programistów (nawet niektórych maniaków z Java), którzy używają tego w swoich przykładach. Wątpię, czy to jest dobra praktyka kodowania? : O –

+0

@bomslang Wiele sprowadzi twoje wymagania. Jak zauważył Azodious, nie klonowanie (udowodnienie jakiejkolwiek innej kopii danych) może prowadzić do nieoczekiwanych problemów dla twojej klasy, ale musisz zdecydować, czy takie zachowanie chcesz. Powodem, dla którego prawdopodobnie tego nie widzisz, jest to, że większość osób pisze więcej. Jeśli spojrzysz na interfejs API Swing, zobaczysz wiele przykładowych praktyk, gdy zwrócisz 'Wymiar", klasa często utworzy nowy obiekt 'Wymiar', używając wewnętrznego odniesienia jako materiału siewnego tej nowej klasy, w zasadzie, klonowanie. – MadProgrammer

+2

Tak, jest. i osobiście użyłem go w przypadku prawie podobnym do twojego przykładu. Ale nie powinno się go używać na ślepo, bo jeśli jakiś ciężki przedmiot zostanie sklonowany, doprowadzi to do problemów z pamięcią. Klonuj tylko te dane, których użytkownik nie powinien modyfikować. – Azodious

2

You clone() or System.arraycopy() na get(), jeśli chcesz zagwarantować, że cały wykres obiektów (zawierający tablicę) jest niezmienny. Odbywa się to zazwyczaj, gdy interfejs API, który udostępnia tablicę, to publiczna i istnieją ograniczenia dotyczące wartości w tablicy lub gdy dostęp do obiektów odbywa się przez wiele wątków. W takich przypadkach niezmienność jest ważna.

Powiedzmy, że masz obiekt GroceryStore, który ma metodę getItemsSortedByPrice(). Przechowujesz elementy w tablicy, która utrzymuje zamówienie według ceny, ale jeśli zwrócisz tę tablicę, kod klienta może ją zmodyfikować i złamać (wewnętrzne) niezmienniki twojego obiektu.

Jeśli jest to kod wewnętrzny (tj.) Nie będący częścią publicznego interfejsu API i wiesz, że nie zmodyfikujesz tablicy, wówczas klonowanie/kopiowanie prawdopodobnie nie jest konieczne, ponieważ szkodzi wydajności bez rzeczywistej korzyści.

Wszystko zależy od kontekstu.

Tablice są po prostu obiektami, a wszystkie (im) reguły/praktyki dotyczące zmienności, które mają zastosowanie do zwykłego obiektu, mają zastosowanie również do tablic.

+1

+1 dla System.arrayCopy (), chociaż zalecam bardziej użyteczną wersję Arrays.copyOf() (która oczywiście używa wewnętrznie System.arrayCopy()) –

1

Myślę, że twój usecase nie pasuje do proponowanego kodu Java. Przykład dotyczy innego przypadku niż twój.

Ostateczna tablica brzmi dla mnie jak Enums i myślę, że to pasuje do Twojego wymagania o wiele lepiej.

5

Jest to omówione w książce "Efektywna Java" przez Joshua Bloch. Istnieje sekcja o nazwie "Wykonuj obronne kopie w razie potrzeby" (Rozdział 39 w drugim wydaniu).

Uważam, że książki Google mogą wyświetlić podgląd sekcji.

Dobra książka do rozpamiętywania takich tematów.

Powiązane problemy