Ich habe kürzlich meine Warnungen in Eclipse durchgesehen und bin auf diese gestoßen:
Es wird eine Compiler-Warnung ausgegeben, wenn die Methode als statisch deklariert werden kann.
[Bearbeiten] Genaues Zitat in der Eclipse-Hilfe, mit Schwerpunkt auf privat und endgültig:
Wenn diese Option aktiviert ist, gibt der Compiler einen Fehler oder eine Warnung für Methoden aus, die privat oder endgültig sind und sich nur auf statische Mitglieder beziehen.
Ja, ich weiß, dass ich es ausschalten kann, aber ich möchte wissen, warum ich es einschalte ?
Warum wäre es gut, jede mögliche Methode als statisch zu deklarieren?
Wird dies Leistungsvorteile bringen? (in einer mobilen Domain)
Wenn Sie auf eine Methode als statisch hinweisen, zeigt dies vermutlich, dass Sie keine Instanzvariablen verwenden und daher in eine Utils-Stilklasse verschoben werden könnten.
Sollte ich am Ende des Tages einfach "Ignorieren" deaktivieren oder die über 100 Warnungen korrigieren, die es mir gegeben hat?
Denken Sie, dass dies nur zusätzliche Schlüsselwörter sind, die den Code verschmutzen , da der Compiler diese Methoden sowieso nur einbindet? (So wie Sie nicht jede Variable deklarieren, die Sie finalisieren können, aber Sie könnten ).
quelle
Antworten:
Wann immer Sie eine Methode schreiben, erfüllen Sie einen Vertrag in einem bestimmten Umfang. Je enger der Bereich ist, desto geringer ist die Wahrscheinlichkeit, dass Sie einen Fehler schreiben.
Wenn eine Methode statisch ist, können Sie nicht auf nicht statische Mitglieder zugreifen. Daher ist Ihr Anwendungsbereich enger. Wenn Sie also (auch in Unterklassen) keine nicht statischen Mitglieder benötigen und niemals benötigen , um Ihren Vertrag zu erfüllen, warum sollten Sie Ihrer Methode Zugriff auf diese Felder gewähren? Wenn Sie
static
in diesem Fall die Methode deklarieren, überprüft der Compiler, ob Sie keine Mitglieder verwenden, die Sie nicht verwenden möchten.Darüber hinaus hilft es den Lesern beim Lesen Ihres Codes, die Art des Vertrags zu verstehen.
Aus diesem Grund wird es als gut angesehen, eine Methode zu deklarieren,
static
wenn tatsächlich ein statischer Vertrag implementiert wird.In einigen Fällen bedeutet Ihre Methode nur etwas relativ zu einer Instanz Ihrer Klasse, und es kommt vor, dass ihre Implementierung tatsächlich kein nicht statisches Feld oder keine nicht statische Instanz verwendet. In solchen Fällen würden Sie die Methode nicht markieren
static
.Beispiele dafür, wo Sie das
static
Schlüsselwort nicht verwenden würden :quelle
private
Methode als statisch deklariert werden könnte, sollte dies fast immer der Fall sein. Für jede andere Zugriffsebene sind andere Faktoren zu berücksichtigen, z. B. der dynamische Versand.object.method()
man die aufzurufende Methode auswählt.Hier gibt es kein Konzept zur Optimierung.
Eine
static
Methode liegt darin,static
dass Sie explizit deklarieren, dass die Methode von keiner Instanz der einschließenden Klasse abhängig ist, nur weil dies nicht erforderlich ist. Damit diese Eclipse-Warnung, wie in der Dokumentation angegeben:Wenn Sie keine Instanzvariable benötigen und Ihre Methode privat (kann nicht von außen aufgerufen werden) oder final (kann nicht überschrieben werden) ist, gibt es keinen Grund, eine normale Methode anstelle einer statischen Methode zu verwenden. Eine statische Methode ist von Natur aus sicherer, nur weil Sie weniger Dinge damit tun dürfen (sie benötigt keine Instanz, Sie haben kein implizites
this
Objekt).quelle
Ich habe keine Informationen über die Leistung, ich nehme an, es ist höchstens geringfügig besser, da der Code keinen dynamischen Versand basierend auf dem Typ durchführen muss.
Ein viel stärkeres Argument gegen das Refactoring in statische Methoden ist jedoch, dass die derzeitige Verwendung von statischen Methoden als schlechte Praxis angesehen wird. Statische Methoden / Variablen lassen sich nicht gut in eine objektorientierte Sprache integrieren und sind auch schwer richtig zu testen. Dies ist der Grund, warum einige neuere Sprachen ganz auf das Konzept statischer Methoden / Variablen verzichten oder versuchen, es auf eine Weise in die Sprache zu verinnerlichen, die mit OO besser funktioniert (z. B. Objekte in Scala).
Meistens benötigen Sie statische Methoden, um Funktionen zu implementieren, die nur Parameter als Eingabe verwenden und eine Ausgabe damit erzeugen (z. B. Dienstprogramm- / Hilfsfunktionen). In modernen Sprachen gibt es ein erstklassiges Funktionskonzept, das dies ermöglicht, also statisch wird nicht gebraucht. In Java 8 sind Lambda-Ausdrücke integriert, daher bewegen wir uns bereits in diese Richtung.
quelle
private static
Methoden, so dass Sie sie nicht verspotten müssen1. Deklarationsmethode
static
Dies bietet einen leichten Leistungsvorteil. Was jedoch nützlicher ist, ist die Verwendung, ohne dass eine Objektinstanz zur Hand ist (denken Sie beispielsweise an die Factory-Methode oder das Abrufen eines Singletons). Es dient auch dem dokumentatorischen Zweck, die Art der Methode zu erläutern. Dieser Dokumentationszweck sollte nicht ignoriert werden, da er den Lesern des Codes und den Benutzern der API einen unmittelbaren Hinweis auf die Art der Methode gibt und auch dem ursprünglichen Programmierer als Denkwerkzeug dient - es hilft, die beabsichtigte Bedeutung explizit anzugeben Sie denken auch klar und produzieren Code mit besserer Qualität (ich denke, basierend auf meiner persönlichen Erfahrung, aber die Leute sind anders). Zum Beispiel ist es logisch und daher wünschenswert, zwischen Methoden zu unterscheiden, die mit einem Typ arbeiten, und Methoden, die auf eine Instanz des Typs wirken (wie von ausgeführt)Jon Skeet in seinem Kommentar zu einer C # -Frage ).Ein weiterer Anwendungsfall für
static
Methoden ist die Nachahmung der prozeduralen Programmierschnittstelle. Denken Sie an diejava.lang.System.println()
Klasse und die darin enthaltenen Methoden und Attribute. Die Klassejava.lang.System
wird eher als Gruppierungsnamenraum als als instanziierbares Objekt verwendet.2. Wie kann Eclipse (oder eine andere programmierte oder andere Art von - biokomposierbarer oder nicht biokomposierbarer - Entität) sicher wissen, welche Methode als statisch deklariert werden kann? Selbst wenn eine Basisklasse nicht auf Instanzvariablen zugreift oder nicht statische Methoden aufruft, können sich die Dinge durch den Vererbungsmechanismus ändern. Nur wenn die Methode nicht durch das Erben der Unterklasse überschrieben werden kann, können wir mit 100% iger Sicherheit behaupten, dass die Methode wirklich deklariert werden kann
static
. Das Überschreiben einer Methode ist genau in beiden Fällen unmöglichprivate
(Keine Unterklasse kann es direkt verwenden und weiß im Prinzip nicht einmal davon) oderfinal
(Selbst wenn die Unterklasse darauf zugreifen kann, gibt es keine Möglichkeit, die Methode so zu ändern, dass sie auf Instanzdaten oder -funktionen verweist.)Daher die Logik der Eclipse-Option.
3. Das Originalposter fragt außerdem: " Wenn Sie auf eine Methode als statisch hinweisen, zeigt dies vermutlich, dass Sie keine Instanzvariablen verwenden und daher in eine Utils-Stilklasse verschoben werden könnten. " Dies ist ein sehr guter Punkt. Manchmal wird diese Art von Designänderung durch die Warnung angezeigt.
Es ist eine sehr nützliche Option, die ich persönlich aktivieren würde, wenn ich Eclipse verwenden und in Java programmieren würde.
quelle
Siehe Samuels Antwort, wie sich der Umfang der Methode ändert. Ich denke, dies ist der Hauptaspekt, um eine Methode statisch zu machen.
Sie haben auch nach der Leistung gefragt:
Es kann zu einem geringfügigen Leistungsgewinn kommen, da für einen Aufruf einer statischen Methode die implizite Referenz "this" nicht als Parameter benötigt wird.
Diese Auswirkungen auf die Leistung sind jedoch sehr gering. Daher dreht sich alles um den Umfang.
quelle
Aus den Android-Leistungsrichtlinien:
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
quelle
Nun, die Eclipse-Dokumentation sagt über die fragliche Warnung:
Ich denke, es sagt so ziemlich alles. Wenn die Methode privat und endgültig ist und sich nur auf statische Elemente bezieht, kann die betreffende Methode genauso gut als statisch deklariert werden. Dadurch wird deutlich, dass wir nur von dort aus auf statische Inhalte zugreifen möchten.
Ich glaube ehrlich gesagt nicht, dass es einen anderen mysteriösen Grund dafür gibt.
quelle
Mir fehlten einige Zahlen für die Geschwindigkeitsunterschiede. Also habe ich versucht, sie zu vergleichen, was sich als nicht so einfach herausstellte: Die Java-Schleife wird nach einigen Läufen / JIT-Fehlern langsamer?
Ich habe endlich Caliper verwendet und die Ergebnisse sind die gleichen wie beim Ausführen meiner Tests von Hand:
Es gibt keinen messbaren Unterschied für statische / dynamische Anrufe. Zumindest nicht für Linux / AMD64 / Java7.
Die Caliper-Ergebnisse finden Sie hier: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercent.scen. CMSLargeSplitSurplusPercent, Szenario.vmSpec.options.CMSSmallCoalSurplusPercent, Szenario.vmSpec.options.CMSSmallSplitSurplusPercent, Szenario.vmSpec.options.FLSLargestBlockCoalesceProximity.Sp.cm
und meine eigenen Ergebnisse sind:
Die Caliper Test Klasse war:
Und meine eigene Testklasse war:
quelle
Die Methoden, die Sie als statisch deklarieren können, erfordern keine Instanziierung, z
Was Sie dann im Gegenzug in jeder anderen Klasse aufrufen können, ohne diese Klasse zu instanziieren.
... Aber das wissen Sie wahrscheinlich schon. Es bietet Ihnen an sich keine wirklichen Vorteile, außer dass Sie klarer machen, dass die Methode keine Instanzvariablen verwendet.
Mit anderen Worten, Sie können es am sichersten einfach vollständig ausschalten. Wenn Sie wissen, dass Sie eine Methode niemals in anderen Klassen verwenden werden (in diesem Fall sollte sie nur privat sein), muss sie überhaupt nicht statisch sein.
quelle