Dlaczego mają prywatne metody statyczne?

68

Chciałem tylko wyjaśnić moje pytanie. Jaki jest sens posiadania prywatnej metody statycznej, a nie zwykłej metody z prywatną widocznością?

Myślałbym, że zaletą posiadania metody statycznej jest to, że można ją wywoływać bez wystąpienia klasy, ale skoro jest ona prywatna, to czy jest w tym sens, że jest statyczna?

Jedynym powodem, dla którego mogę myśleć, jest to, że pomaga koncepcyjnie zrozumieć metodę na poziomie klasy, a nie na poziomie obiektu.

Rehan Naqvi
źródło
32
Tak, jest powód. Twoje publiczne / domyślne metody statyczne mogą nadal wywoływać twoją prywatną statykę. Czy w ogóle należy stosować metody statyczne i kiedy właściwe jest stosowanie jakichkolwiek metod prywatnych, to osobne pytania, więc uważaj, aby ich nie mieszać z tym pytaniem.
2
Szybki przykład - metoda fabryczna używana przez klasę wewnętrzną zapobiegająca wywołaniu przez inne klasy (musisz przejść przez metodę fabryczną, aby uzyskać instancję klasy).
2
@MattFenwick: powinieneś opublikować to jako odpowiedź.
Doc Brown
9
Tworząc metodę statyczną, mówisz również, że nie odczytuje ona ani nie zapisuje zmiennych zmiennych instancji. Metoda, która nie wchodzi w interakcje ze zmiennymi instancji, jest często łatwiejsza do przenoszenia i refaktoryzacji w inne miejsca.
Mark Rogers
1
Nie zapominaj, że bez względu na to, czy metoda statyczna jest prywatna, wewnętrzna czy publiczna, nadal nie jest bezpieczna dla wątków bez konkretnego wysiłku synchronizacji kodu z twojej strony.
Craig

Odpowiedzi:

70

Charakter bycia statycznym jest niezależny od widoczności.

Powody, dla których chcesz mieć metodę statyczną (niektóre kody, które nie zależą od elementów niestatycznych) nadal będą przydatne. Ale może nie chcesz, aby ktokolwiek / cokolwiek innego go używał, tylko twoja klasa.

Miyamoto Akira
źródło
3
Myślę, że jesteś na dobrej drodze, ale myślę, że brakuje ci kluczowego punktu. Większość metod statycznych ma zerowe skutki uboczne (są to skutecznie funkcje, a nie metody) - dlatego właśnie stały się statyczne. Argument, że są prywatni, brzmi: „Jeśli nie mają żadnych skutków ubocznych, dlaczego nie upublicznić ich, aby promować ponowne użycie kodu”. To jest kluczowy punkt: kiedy robimy to prywatnym, zwykle dzieje się tak dlatego, że chcemy, abyś ponownie wykorzystał całą klasę, która używa tej prywatnej metody, a nie tylko tej metody.
corsiKa
Muszę powiedzieć, że nigdy tego nie robiłem ani nie widziałem tego zachowania. Kilka razy robiłem to dla metod pomocniczych do publicznych klas statycznych.
Miyamoto Akira
1
@corsiKa: Skutki uboczne nie są problemem. Uczynienie statycznego członka klasy nieprywatnym skutecznie obiecuje, że każda przyszła wersja klasy będzie zawierała tę samą metodę o tej samej nazwie, która robi to samo. Jeśli potrzeby się zmienią, a przyszła wersja klasy może nie potrzebować metody, która działa dokładnie tak , jak obecnie, metoda prywatna może być bezpiecznie zastąpiona metodą, która lepiej spełnia nowe potrzeby klasy. Jako prosty przykład, załóżmy, że klasa musi metodę, która pobiera ciąg i wykonuje podstawienia jak <do &lt;itp Kiedy jest napisane ...
Supercat
1
... wiadomo, że ciągi, które są przekazywane, nie zawierają żadnych znaków ampersand i dlatego nie konwertują się &na &amp;[gdybym pisał kod, przekonwertowałbym &na to, &amp;nawet jeśli nie spodziewałem się, że będzie to konieczne, ale przypuśćmy, że nie]. Jest to później staje się niezbędne do obsługi ampersandy, ale metoda jest publiczna, zmieniając go poszerzyć &do &amp;mogłaby złamać kod na zewnątrz, która wykonuje swój &-to- &amp;podstawienie. Jeśli metoda jest prywatna, można ją jednak naprawić &bez powodowania problemów z jakimkolwiek kodem zewnętrznym.
supercat
To co najmniej interesujący problem, ale nie rozumiem, jak to jest statyczne, że sprawia, że ​​jest to większy problem niż brak statyczności, co jest kluczem do tego problemu. Jeśli będziemy postępować zgodnie z twoją logiką, wszystko na świecie ponownie wszystko zaimplementuje, ponieważ „omg, a co, jeśli któregoś dnia wystąpi błąd lub wymagania?”
corsiKa
26

Dość częstym powodem (w Javie) może być inicjowanie niezmiennych zmiennych pola w konstruktorze za pomocą prostej private staticmetody ograniczania bałaganu konstruktora.

  • To jest private: klasy zewnętrzne nie powinny tego widzieć.
  • Jest static: może wykonać jakąś operację, niezależny 1 stanu klasy przyjmującego.

Nieco wymyślony przykład jest następujący ...

na przykład:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 Zakładając, że nie ma interakcji z innymi staticzmiennymi.

Sheldon Warkentin
źródło
15
Jest to tym bardziej cenne, gdy trzeba przekazać wyprowadzone (obliczone) argumenty do konstruktora nadklasy. super(...)Wezwanie musi być pierwsza linia swojej klasie konstruktora, więc nie można zadeklarować zmienne lokalne, które pomogą Ci zorientować, co przejść do super rozmowy. Jednakże, może zadzwonić (prywatny) statyczne metody, które wykorzystują wiele linii, jak to konieczne, aby wypracować wartość przejść do super konstruktora.
Andrzej Doyle,
zauważ, że istnieje możliwość statycznego bloku inicjalizującego
Franz Ebner
13

Typowym przypadkiem użycia private staticmetody jest metoda narzędziowa

  1. używane tylko przez tę jedną klasę
  2. jest niezależny od wewnętrznego stanu tej klasy
Philipp
źródło
12

Widzisz, że masz kilka wierszy kodu, które są powtarzane w wielu twoich metodach, więc decydujesz się wyodrębnić je do jednej metody, ponieważ powielony kod nie jest dobry.

Metoda jest prywatna, ponieważ nie jest przeznaczona do powszechnego użytku i nie chcesz, aby wywoływany był niepowiązany kod. (Omów ten punkt w komentarzach…)

Ponieważ metoda nie ma dostępu do żadnych pól instancji, można ją ustawić na statyczną, czyniąc ją statyczną, można ją łatwiej zrozumieć, a może nawet trochę szybciej.

Potem .... (może teraz, może później, może nigdy)

Gdy metoda stanie się statyczna, jasne jest , że można ją przenieść z klasy, powiedzmy do klasy jedności.

Łatwo jest również przekształcić go w metodę instancji jednego z jego parametrów, często tam powinien być kod.

Ian
źródło
Podoba mi się ta odpowiedź, ale czy masz jakieś aktualne odniesienia? „a może nawet trochę szybszy”
Magnilex
@Magnilex, Wskaźnik „ten” nie jest przekazywany do metod klasy statycznej, dlatego będą one zwykle szybsze niż metody instancji statycznych, chyba że kompilator wykryje, że „to” nie jest używane w metodzie instancji (mało prawdopodobne).
Ian
2

Mogę wymyślić co najmniej dwa powody, dla których potrzebujesz statycznej prywatnej metody w klasie.

1: Twoje instancje mają powód, aby wywoływać metodę statyczną, której nie chcesz wywoływać bezpośrednio, być może dlatego, że dzieli dane między wszystkimi instancjami twojej klasy.

2: Twoje publiczne metody statyczne mają podprogramy, których nie chcesz wywoływać bezpośrednio. Metoda jest nadal wywoływana bez wystąpienia, po prostu nie bezpośrednio.

Oczywiście, „to pomaga klasie mieć sens” to dobry powód sam w sobie.

DougM
źródło
1

Ogólnie, jeśli stwierdzę, że piszę prywatne metody statyczne, biorę to za wskazówkę, że jest coś, co powinienem był osobno modelować.

Ponieważ nie są one powiązane ze stanem konkretnej instancji obiektu, zbiór publicznych i prywatnych metod statycznych może tworzyć całkowicie odrębną klasę z własnymi metodami semantycznymi i niestatycznymi.

(Inna wskazówka jest taka, że ​​jeśli stwierdzę, że mam wiele metod statycznych (publicznych i prywatnych), z których wszystkie mają wspólny parametr pewnego rodzaju, lepiej byłoby, gdyby byli członkami tego typu.)

Tak więc, aby odpowiedzieć na twoje pytanie, prywatne metody statyczne pojawiają się, gdy klasa udostępnia grupę powiązanych metod, które są niezależne od instancji tej klasy. (... a ponieważ są niezależni, może im być lepiej w swojej klasie.)

Obrabować
źródło
-1

Bardzo prosty przykład, jaki mogę wymyślić, to jeśli chcesz wykonać pewne przetwarzanie argumentów wejściowych (lub pewnych manipulacji), które są przekazywane do funkcji głównej. Tak więc w tym przypadku, jeśli przetwarzanie jest duże i ta sama funkcjonalność nie będzie używana nigdzie indziej, sensowne będzie posiadanie funkcji prywatnej, ponieważ nie będzie ona używana / wywoływana z jakiegokolwiek innego miejsca + static, ponieważ main jest static.

techExplorer
źródło