Warum private statische Methoden?

68

Ich wollte nur eine Frage klären, die ich habe. Was ist der Sinn einer privaten statischen Methode im Gegensatz zu einer normalen Methode mit privater Sichtbarkeit?

Ich hätte gedacht, dass ein Vorteil einer statischen Methode darin besteht, dass sie ohne eine Instanz einer Klasse aufgerufen werden kann, aber gibt es überhaupt einen Grund dafür, dass sie statisch ist, da sie privat ist?

Der einzige Grund, den ich mir vorstellen kann, ist, dass es das konzeptionelle Verständnis der Methode auf Klassenebene und nicht auf Objektebene erleichtert.

Rehan Naqvi
quelle
32
Ja, es gibt einen Grund. Ihre öffentlichen / statischen Standardmethoden können weiterhin Ihre privaten Statiken aufrufen. Ob statische Methoden überhaupt verwendet werden sollten und ob es angemessen ist, private Methoden jeglicher Art zu verwenden, sind separate Fragen. Verwechseln Sie sie daher nicht mit dieser Frage.
2
Schnelles Beispiel - Factory-Methode, die von einer inneren Klasse verwendet wird, um den Aufruf durch andere Klassen zu verhindern (Sie müssen die Factory-Methode durchgehen, um eine Instanz der Klasse abzurufen).
2
@MattFenwick: Du solltest dies als Antwort posten.
Doc Brown
9
Indem Sie eine Methode statisch machen, sagen Sie auch, dass sie keine Instanzvariablen liest oder in diese schreibt. Eine Methode, die nicht mit Instanzvariablen interagiert, ist häufig einfacher zu verschieben und an andere Stellen umzugliedern.
Mark Rogers
1
Vergessen Sie nicht, dass eine statische Methode, unabhängig davon, ob sie privat, intern oder öffentlich ist, immer noch nicht threadsicher ist, ohne dass Sie sich um eine spezifische Codesynchronisierung bemühen.
Craig

Antworten:

70

Die Eigenschaft, statisch zu sein, ist unabhängig von der Sichtbarkeit.

Die Gründe, aus denen Sie eine statische Methode benötigen (einige Codes, die nicht von nicht statischen Elementen abhängen), sind weiterhin nützlich. Aber vielleicht willst du nicht, dass irgendjemand es benutzt, nur deine Klasse.

Miyamoto Akira
quelle
3
Ich denke, Sie sind auf dem richtigen Weg, aber ich denke auch, dass Sie einen wichtigen Punkt verpassen. Die meisten statischen Methoden haben keine Nebenwirkungen (sie sind effektiv Funktionen, keine Methoden) - deshalb werden sie in erster Linie statisch gemacht. Das Argument gegen sie ist "Wenn sie keine Nebenwirkungen haben, warum sie nicht öffentlich machen, um die Wiederverwendung von Code zu fördern". Das ist der entscheidende Punkt: Wenn wir es privat machen, ist es normalerweise so, dass Sie die gesamte Klasse wiederverwenden möchten , die diese private Methode verwendet, nicht nur diese Methode.
corsiKa
Ich muss sagen, dass ich das noch nie getan oder gesehen habe. Die wenigen Male, die ich getan habe, waren Hilfsmethoden für öffentliche statische Klassen.
Miyamoto Akira
1
@ CorsiKa: Nebenwirkungen sind nicht das Problem. Wenn Sie ein statisches Mitglied einer Klasse nicht-privat machen, verspricht dies, dass jede zukünftige Version einer Klasse dieselbe Methode mit demselben Namen enthält, die dasselbe tut. Wenn sich die Anforderungen ändern und eine zukünftige Version der Klasse möglicherweise keine Methode benötigt, die genauso funktioniert wie die aktuelle, kann eine private Methode sicher durch eine ersetzt werden, die die neuen Anforderungen der Klasse besser erfüllt. Nehmen wir als einfaches Beispiel an, dass eine Klasse eine Methode benötigt, die einen String nimmt und Ersetzungen wie <den folgenden ausführt &lt;. Wenn sie geschrieben wird ...
supercat
1
... Die übergebenen Zeichenfolgen enthalten bekanntermaßen kein kaufmännisches Und und werden daher nicht &in &amp;[konvertiert &, &amp;wenn ich den Code schreibe, würde ich in konvertieren , auch wenn ich nicht damit gerechnet hätte, dass dies erforderlich ist, aber angenommen es tut nicht]. Es wird später notwendig, kaufmännisches Und zu behandeln, aber die Methode ist öffentlich und ändert sie in expand &, &amp;um externen Code zu &beschädigen, der seine eigene &amp;Ersetzung durchführt. Wenn die Methode privat ist, kann sie behoben werden, &ohne Probleme mit externem Code zu verursachen.
Supercat
Das ist, gelinde gesagt, ein interessantes Problem, aber ich verstehe nicht, dass es eher ein Problem ist, wenn es statisch ist, als wenn es nicht statisch ist, was der Schlüssel zu diesem Problem ist. Wenn wir Ihrer Logik folgen, würde alles überall alles neu implementieren, weil "omg, was ist, wenn sich eines Tages ein Fehler oder Anforderungen ändern?"
CorsiKa
26

Ein ziemlich häufiger Grund (in Java) wäre, unveränderliche Feldvariablen in einem Konstruktor mit einer einfachen private staticMethode zu initialisieren, um das Durcheinander der Konstruktoren zu verringern.

  • Es ist private: Externe Klassen sollten es nicht sehen.
  • Es ist static: es eine Operation durchführen kann, unabhängig 1 von dem Zustand der Host - Klasse.

Es folgt ein etwas ausgeklügeltes Beispiel ...

z.B:

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 Vorausgesetzt, es hat keine Wechselwirkung mit anderen staticVariablen.

Sheldon Warkentin
quelle
15
Dies ist umso wertvoller, wenn Sie abgeleitete (berechnete) Argumente an den Konstruktor einer Oberklasse übergeben müssen. Der super(...)Aufruf muss die erste Zeile des Konstruktors Ihrer Klasse sein, sodass Sie keine lokalen Variablen deklarieren können, um herauszufinden, was an den Super-Aufruf übergeben werden soll. Sie können jedoch (private) statische Methoden aufrufen, die so viele Zeilen wie nötig verwenden, um den an den Superkonstruktor zu übergebenden Wert zu ermitteln.
Andrzej Doyle
Beachten Sie, dass die Möglichkeit eines statischen Initialisierungsblocks besteht
Franz Ebner
13

Ein üblicher Anwendungsfall für eine private staticMethode ist eine Utility-Methode

  1. wird nur von dieser einen Klasse verwendet
  2. ist unabhängig vom internen Zustand dieser Klasse
Philipp
quelle
12

Sie sehen, dass Sie einige Codezeilen haben, die in vielen Ihrer Methoden wiederholt werden, und beschließen, sie in eine einzige Methode zu extrahieren, da duplizierter Code nicht gut ist.

Sie machen die Methode privat, da sie nicht für die allgemeine Verwendung vorgesehen ist und Sie keinen unabhängigen Code benötigen, der sie aufruft. (Diskutieren Sie diesen Punkt in den Kommentaren….)

Da die Methode auf keine Instanzfelder zugreift, kann sie statisch gemacht werden. Indem Sie sie statisch machen, machen Sie sie verständlicher und möglicherweise sogar ein wenig schneller.

Dann .... (Vielleicht jetzt, vielleicht später, vielleicht nie)

Sobald die Methode statisch gemacht wurde, ist klar, dass sie aus der Klasse verschoben werden kann, beispielsweise zu einer Einheitsklasse.

Es ist auch einfach, es in eine Instanzmethode eines seiner Parameter umzuwandeln. Oft ist dies der Ort, an dem sich der Code befinden sollte.

Ian
quelle
Ich mag diese Antwort, aber haben Sie eine aktuelle Referenz dafür? "und vielleicht sogar ein bisschen schneller"
Magnilex
@Magnilex, Der Zeiger "this" wird nicht an statische Klassenmethoden übergeben, daher sind sie in der Regel schneller als statische Instanzmethoden, es sei denn, der Compiler stellt fest, dass "this" in der Instanzmethode nicht verwendet wird (unwahrscheinlich).
Ian
2

Ich kann mir mindestens zwei Gründe vorstellen, warum Sie eine statische private Methode für eine Klasse benötigen würden.

1: Ihre Instanzen haben Grund, eine statische Methode aufzurufen, die Sie nicht direkt aufrufen möchten, möglicherweise, weil sie Daten zwischen allen Instanzen Ihrer Klasse gemeinsam nutzt.

2: Ihre öffentlichen statischen Methoden verfügen über Subroutinen, die Sie nicht direkt aufrufen möchten. Die Methode wird immer noch ohne Instanz aufgerufen, nur nicht direkt.

Natürlich ist "es hilft der Klasse, einen Sinn zu ergeben" ein guter Grund für sich.

DougM
quelle
1

Wenn ich feststelle, dass ich private statische Methoden schreibe, nehme ich dies im Allgemeinen als Hinweis darauf, dass es etwas gibt, das ich separat hätte modellieren sollen.

Da sie nicht an den Status einer bestimmten Objektinstanz gebunden sind, kann eine Sammlung öffentlicher und privater statischer Methoden eine völlig separate Klasse mit eigenen semantischen und nicht statischen Methoden bilden.

(Ein weiterer Hinweis: Wenn ich finde, dass ich viele statische Methoden (öffentlich und privat) habe, die alle einen gemeinsamen Parameter eines bestimmten Typs haben, sind sie möglicherweise besser als Mitglieder dieses Typs geeignet.)

Um Ihre Frage zu beantworten, werden private statische Methoden angezeigt, wenn eine Klasse eine Gruppe verwandter Methoden bereitstellt, die von einer Instanz dieser Klasse unabhängig sind. (... und da sie unabhängig sind, sind sie vielleicht in ihrer eigenen Klasse besser dran.)

rauben
quelle
-1

Ein sehr einfaches Beispiel, das mir einfällt, ist, wenn Sie einige Eingaben (oder Manipulationen) verarbeiten möchten, die an die Hauptfunktion übergeben werden. In diesem Fall ist es also sinnvoll, eine private Funktion zu haben, wenn die Verarbeitung groß ist und dieselbe Funktionalität nirgendwo anders verwendet wird, da sie nirgendwo anders verwendet / aufgerufen wird. + Static, da main statisch ist.

techExplorer
quelle