CharSequence
= interfejs
String
= konkretna implementacja
Powiedziałeś:
konwersja z jednego na drugi
Nie ma konwersji z String
.
- Każdy
String
obiekt jestCharSequence
.
- Każdy
CharSequence
może wyprodukować String
. Zadzwoń CharSequence::toString
. Jeśli CharSequence
zdarza się, że a String
, to metoda zwraca odwołanie do własnego obiektu.
Innymi słowy, każdy String
jest CharSequence
, ale nie każdy CharSequence
jest String
.
Programowanie do interfejsu
Programując w Androidzie, większość wartości tekstowych jest oczekiwana w CharSequence.
Dlaczego? Jakie są korzyści i jakie są główne skutki używania CharSequence w stosunku do String?
Zasadniczo programowanie w interfejsie jest lepsze niż programowanie w konkretnych klasach. Daje to elastyczność, dzięki czemu możemy przełączać się między konkretnymi implementacjami konkretnego interfejsu bez łamania innego kodu.
Tworząc interfejs API, który ma być używany przez różnych programistów w różnych sytuacjach, napisz swój kod, aby udostępnić i wziąć jak najbardziej ogólne interfejsy. Daje to programistom wywołującym swobodę korzystania z różnych implementacji tego interfejsu, w zależności od tego, która implementacja jest najlepsza dla danego kontekstu.
Na przykład spójrz na środowisko Java Collections Framework . Jeśli API daje lub bierze uporządkowanego zbioru obiektów, deklarują swoje metody, jak przy użyciu List
zamiast ArrayList
, LinkedList
albo jakakolwiek inna realizacja 3rd partia List
.
Pisząc szybką i brudną małą metodę, która ma być używana tylko przez Twój kod w jednym określonym miejscu, w przeciwieństwie do pisania interfejsu API do użycia w wielu miejscach, nie musisz zawracać sobie głowy bardziej ogólnym interfejsem niż konkretnym klasa. Ale nawet wtedy korzystanie z najbardziej ogólnego interfejsu, jaki możesz, może zaszkodzić.
Jakie są główne różnice i jakich problemów można się spodziewać podczas ich używania,
- Z
String
wiesz, że masz jeden fragment tekstu, w całości w pamięci i jest niezmienna.
- Dzięki
CharSequence
nie wiesz, jakie mogą być szczególne cechy konkretnej implementacji.
CharSequence
Przedmiot może stanowić ogromny fragment tekstu, a zatem ma wpływ na pamięć. Lub może być wiele fragmentów tekstu śledzonych osobno, które będą musiały zostać połączone podczas połączenia toString
, a zatem występują problemy z wydajnością. Implementacja może nawet pobierać tekst ze zdalnej usługi, a zatem ma wpływ na opóźnienia.
i przechodząc od jednego do drugiego?
Zasadniczo nie będziesz nawracał się w tę iz powrotem. A String
jest a CharSequence
. Jeśli twoja metoda deklaruje, że wymaga a CharSequence
, programista wywołujący może przekazać String
obiekt lub przekazać coś innego, na przykład a StringBuffer
lub StringBuilder
. Kod twojej metody będzie po prostu używał tego, co zostało przekazane, wywołując dowolną z CharSequence
metod.
Konwersja jest najbliższa, jeśli Twój kod otrzyma CharSequence
i wiesz, że potrzebujesz String
. Być może łączysz się ze starym kodem zapisanym w String
klasie, a nie w CharSequence
interfejsie. A może Twój kod będzie intensywnie pracował z tekstem, na przykład powtarzając pętle lub analizując w inny sposób. W takim przypadku chcesz wykonać jeden możliwy hit wydajności tylko raz, więc zadzwoń z toString
góry. Następnie kontynuuj pracę, używając tego, co wiesz, że jest pojedynczym fragmentem tekstu całkowicie w pamięci.
Zakręcona historia
Zanotuj komentarze do zaakceptowanej odpowiedzi . CharSequence
Interfejs został zamontować na istniejących struktur klasowych, więc istnieją pewne ważne subtelności ( equals()
& hashCode()
). Zwróć uwagę na różne wersje Javy (1, 2, 4 i 5) oznaczone na klasach / interfejsach - z biegiem lat sporo rezygnacji. Idealnie CharSequence
byłoby na miejscu od samego początku, ale takie jest życie.
Mój diagram klas poniżej może pomóc zobaczyć duży obraz typów ciągów w Javie 7/8. Nie jestem pewien, czy wszystkie są obecne w Androidzie, ale ogólny kontekst może nadal być dla Ciebie przydatny.