Printf został dodany do Javy w wersji 1.5, ale nie mogę znaleźć sposobu, aby wysłać dane wyjściowe do łańcucha zamiast do pliku (co robi sprintf w C). Czy ktoś wie jak to zrobić?
źródło
Printf został dodany do Javy w wersji 1.5, ale nie mogę znaleźć sposobu, aby wysłać dane wyjściowe do łańcucha zamiast do pliku (co robi sprintf w C). Czy ktoś wie jak to zrobić?
Ciągi są niezmiennymi typami. Nie możesz ich modyfikować, zwracaj tylko nowe wystąpienia ciągów.
Z tego powodu formatowanie za pomocą metody instancji nie ma większego sensu, ponieważ należałoby ją wywołać w następujący sposób:
String formatted = "%s: %s".format(key, value);
Oryginalni autorzy Java (i autorzy .NET) zdecydowali, że metoda statyczna ma większy sens w tej sytuacji, ponieważ nie modyfikujesz obiektu docelowego, ale zamiast tego wywołujesz metodę formatowania i przekazujesz ciąg wejściowy.
Oto przykład, dlaczego format()
miałby być głupi jako metoda instancji. W .NET (i prawdopodobnie w Javie) Replace()
jest metodą instancji.
Możesz to zrobić:
"I Like Wine".Replace("Wine","Beer");
Jednak nic się nie dzieje, ponieważ ciągi są niezmienne. Replace()
próbuje zwrócić nowy ciąg, ale jest on przypisany do niczego.
Powoduje to wiele typowych błędów debiutantów, takich jak:
inputText.Replace(" ", "%20");
Ponownie nic się nie dzieje, zamiast tego musisz zrobić:
inputText = inputText.Replace(" ","%20");
Jeśli zrozumiesz, że ciągi są niezmienne, ma to doskonały sens. Jeśli nie, to jesteś po prostu zdezorientowany. Właściwym miejscem Replace()
byłoby, gdzie format()
jest, jako statyczna metoda String
:
inputText = String.Replace(inputText, " ", "%20");
Teraz nie ma wątpliwości, co się dzieje.
Prawdziwe pytanie brzmi: dlaczego autorzy tych ram zdecydowali, że jedna powinna być metodą instancji, a druga statyczna? Moim zdaniem oba są bardziej elegancko wyrażone jako metody statyczne.
Niezależnie od twojej opinii, prawda jest taka, że masz mniejszą skłonność do popełniania błędów przy użyciu wersji statycznej, a kod jest łatwiejszy do zrozumienia (brak ukrytych błędów).
Oczywiście istnieją pewne metody, które są doskonałe jako metody instancji, weź String.Length ()
int length = "123".Length();
W tej sytuacji jest oczywiste, że nie próbujemy modyfikować „123”, po prostu go sprawdzamy i zwracamy jego długość. Jest to idealny kandydat na metodę instancji.
Moje proste zasady dotyczące metod instancji na obiektach niezmiennych:
Oba rozwiązania symulują printf, ale w inny sposób. Na przykład, aby przekonwertować wartość na ciąg szesnastkowy, masz 2 następujące rozwiązania:
z
format()
najbliżejsprintf()
:z
replace(char oldchar , char newchar)
, nieco szybszym, ale dość ograniczonym:Istnieje trzecie rozwiązanie polegające na dodaniu char do
ret
jednego po drugim (char to liczby, które się dodają !), Na przykład:... ale to byłoby naprawdę brzydkie.
źródło
Możesz zrobić printf do wszystkiego, co jest OutputStream z PrintStream. Jakoś tak, drukując do strumienia ciągów:
Strumień ciągu można utworzyć w następujący sposób ByteArrayOutputStream:
źródło