2010-08-02 11 views
7

Powiel możliwe:
Why is String final in Java?Dlaczego klasa String jest ostateczna?

Istnieją różne momenty w moim życiu programowania że życzył klasa String nie była ostateczna/zamknięte/NotInheritable.

W jaki sposób architekci językowi próbują przeszkodzić mi w wykonaniu tego zadania, rzucają kluczem małpa do dzieła.

Co to są małpie klucze, które architekci językowi chcieliby uniemożliwić mi wrzucenie do prac poprzez ograniczenie mnie przed rozszerzeniem klasy String?

Czy mógłbyś podać listę plusów minus rozszerzalnej klasy ciągów?

+0

Zdaję sobie sprawę, że istnieją inne klasy, takie jak numeryczne, które również są zamknięte. Możemy zacząć od analizy String, ale twoje komentarze nie muszą być ograniczone do String. –

+0

+1 ... Chciałem też raz w życiu rozszerzyć klasę String, chociaż nie pamiętam, dlaczego –

+0

Jak już wspomniałeś java (tag), zostało to wcześniej zadane: http://stackoverflow.com/questions/2068804/why-is-string-final-in-java –

Odpowiedz

5

Łańcuch to immutable class, co oznacza, że ​​nie można zmienić jego stanu po utworzeniu. Jeśli mógłbyś zmodyfikować ciąg po przejściu do innej biblioteki lub Mapie, wynik byłby nieprzewidywalny.

Jednym z błędów API Javy jest to, że BigInteger i BigDecimal nie są ostateczne, co oznacza, że ​​należy wykonać obronną kopię tych obiektów podczas odbierania ich z niezaufanego kodu. I odwrotnie, zawsze możesz ufać, że String pozostanie spójny.

nierzetelne BigInteger:

public class DestructiveBigInteger extends BigInteger { 

    public DestructiveBigInteger(String value) { 
     super(value); 
    } 

    public BigInteger add(BigInteger val) { 
     return BigInteger.ONE; // add() method does not behave correctly 
    } 

    public BigInteger subtract(BigInteger val) { 
     throw new UnsupportedOperationException("subtract is broken"); 
    } 
} 

samo nie jest możliwe String. Jak stwierdzono w Effective Java, trzeba wykonać kopie obronne z tych typów obiektów:

public void setValue(BigInteger value) { 
    this.value = new BigInteger(value.toByteArray()); 
} 
+0

Opracowanie, pls. –

+1

Upewnij się, że znasz różnicę między * ostatecznym * słowem kluczowym i * zapieczętowanym * słowem kluczowym. Klasy oznaczone * final * są TAKŻE * skutecznie zapieczętowane *, ale to nie jest prawdziwy punkt słowa kluczowego * final *. Klasa * * * jest ** niezmienna **, co oznacza, że ​​nie można jej modyfikować po utworzeniu. Niezmienne klasy muszą być również zapieczętowane, w przeciwnym razie można dziedziczyć, zastępować i dodawać pewne niezmienne zachowanie. Ciągi są niezmienne w Javie, ponieważ zmienne łańcuchy są ** niebezpieczne **, i, szczerze mówiąc, więcej problemów niż są one warte. Większość współczesnych języków (Python, JavaScript, C#, Java) używa niezmiennych ciągów. – Ender

4

String jest ostateczna, ponieważ stanowi ona niezmienna typu danych. Potworność kolektora wynikałaby z rozszerzenia naiwnego Stringa, ponieważ istnieje wiele bibliotek, które zależą od niezmienności obiektów String.

Rozszerzenie Stringa, aby było zmienne, byłoby niewidoczne dla każdego kodu, przez który przechodzi Sting, ale miałoby bardzo zaskakujące i nieprzyjemne efekty uboczne, jak nagle nie jest w stanie załadować wartości z HashMaps, nawet jeśli dosłownie masz ciąg znaków klucz, ponieważ kod hashCode zostałby przejęty.

+0

Jeśli chciałem użyć łańcucha znaków dla kluczy mapy, użyłbym String. Jeśli chciałem użyć rozszerzonego łańcucha jako klucza do mapy, to właśnie to chcę zrobić - aby uniemożliwić dostęp do niego za pomocą podstawowych obiektów String. Argument o niezmienności wydaje mi się, że nie ma dla mnie wody. –

+0

Ale przedłużony Łańcuch * będzie * Łańcuchem. Więc możesz go użyć jako klucza mapy z String. Brak możliwości wyprowadzania nie powstrzymuje cię przed napisaniem klasy, która rozszerza możliwości String (używając kompozycji). Po prostu przestajemy tworzyć instancje tej klasy w Strings. – jwg

Powiązane problemy