Warum sind statische Variablen, die als böse?
Ich bin ein Java-Programmierer, der neu in den corporate-Welt. Vor kurzem habe ich eine Anwendung entwickelt, mit Groovy und Java. Alle durch den code, den ich schrieb-durchaus eine gute Anzahl von Statik. Ich wurde gebeten, für die senior technical Menge zu reduzieren auf die Anzahl der Statik verwendet. Ich habe gegoogelt über die gleichen, und ich finde, dass viele Programmierer eher gegen die Verwendung von statischen Variablen.
Finde ich statische Variablen, die mehr bequem zu bedienen. Und ich nehme an, dass Sie effizient sind (bitte korrigiert mich wenn ich falsch Liege), weil, wenn ich hatte, um 10.000 Anrufe an eine Funktion innerhalb einer Klasse, ich wäre froh zu machen, die Methode, die statische und verwenden Sie eine einfache Class.methodCall()
auf es statt überladen den Arbeitsspeicher mit 10.000 Instanzen der Klasse, richtig?
Zudem Statik reduzieren die Abhängigkeiten auf die anderen Teile des Codes. Sie können als perfekte Stand-Inhabern. Dazu finde ich, dass die Statik sind weitgehend umgesetzt, in einigen Sprachen wie Smalltalk und Scala. Also, warum ist diese Unterdrückung für Statik weit verbreitet unter den Programmierern (besonders in der Welt von Java)?
PS: bitte korrigieren Sie mich, wenn meine Annahmen über die Statik falsch sind.
Mindestens eine Aussage, die Sie machen, ist ziemlich kurios: "Statik reduzieren die Abhängigkeiten auf die anderen Teile des Codes". Im Allgemeinen werden Sie ziehen Sie die Abhängigkeiten. Den code, wo der Anruf gemacht wird, gebunden ist, sehr eng an den genannten code. Keine Abstraktion, die direkte Abhängigkeit.
Gute Frage... eher ein Programmierer.SE Fragen tho?
Ihren zweiten Absatz wird über ein ganz anderes Thema, nämlich die statische Methoden.
Funktionale Programmierung auch runzelt die Stirn nach unten auf globaler Zustand als gut. Wenn Sie immer (und sollte) zur FP eines Tages bereit sein, zu Graben, den Begriff des globalen Zustands.
InformationsquelleAutor Vamsi Emani | 2011-08-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Statische Variablen darstellen globalen Zustand. Das ist hart zu Grunde geht und schwer zu testen: wenn ich erstellen Sie eine neue Instanz eines Objekts an, ich kann die Vernunft über seine neue Staat innerhalb des tests. Wenn ich code die Verwendung von statischen Variablen sind, könnte es in jedem Staat - und nichts könnte das ändern.
Ich könnte noch eine ganze Weile, aber das größere Konzept zu denken ist, dass je enger der Rahmen etwas ist, desto leichter ist es zu Grunde geht. Wir sind gut im denken über kleine Dinge, aber es ist schwer an die Vernunft über den Zustand der ein-Millionen-line-system, wenn es keine Modularität. Dies gilt für alle möglichen Dinge, von der Möglichkeit, nicht nur statische Variablen.
Platvoet: ich würde sagen, dass bei der Wahl zwischen zwei ansonsten gleich gültig designs, die prüfbar ist der beste. Als testbare ganz sicher nicht gleich gut entwickelt, aber ich habe selten kommen über unüberprüfbare gute designs, und ich denke, Sie sind hinreichend selten, dass ich haben kein problem im Testbarkeit einen general purpose Beitrag Anzeige gegen gutes design.
Platvoet - Testbarkeit betrifft sowohl die Wartbarkeit und Zuverlässigkeit, und ich würde prüfen, diese wichtigen Faktoren in Qualität und design. Sie sind nicht die einzigen Faktoren, sicherlich, aber IMHO die Kosten für jede gegebene code ist eine Kombination von Maschinen-Zyklen, Entwickler Zyklen, und Anwender-Zyklen. Testbarkeit hat zwei dieser drei.
Platvoet - Testbarkeit neigt auch dazu, Auswirkungen auf die Wiederverwendbarkeit, da eine entkoppelte Klasse ist in der Regel einfacher zu verwenden.
M Platvoet - ich bin nicht einverstanden mit deinem ersten Kommentar hier. Ich denke, wenn etwas nicht getestet werden können, dann IST es schlechtes design, weil wenn ich nicht überprüfen kann, kann ich nicht wissen, dass es funktioniert. Würden Sie ein Auto kaufen, wenn der Verkäufer dir gesagt "Das design dieses Modell verhindert, dass Sie nicht getestet, also weiß ich nicht, ob es tatsächlich läuft"? Testbarkeit ist damit von entscheidender Bedeutung für die software (wie auch Autos), dass die zuständigen design-ANFORDERUNGEN, die aufgenommen werden soll.
InformationsquelleAutor Jon Skeet
Seine nicht sehr Objekt-orientiert:
Ein Grund, Statik berücksichtigt werden könnte, "böse" von einigen Menschen wird Sie gegen die Objekt-orientierte Paradigma. Insbesondere verstößt Sie gegen den Grundsatz, dass die Daten gekapselt in Objekten (das können verlängert werden, Informationen ausblenden, etc). Statik, in der Weise, die Sie beschreiben, mit Ihnen, sind im wesentlichen verwenden diese als Globale variable zu vermeiden, Umgang mit Themen wie Umfang. Allerdings werden Globale Variablen ist eines der bestimmenden Merkmale der prozeduralen oder imperativen Programmierung Paradigma, nicht eine Eigenschaft der "gute" Objekt-orientierten code. Dies ist nicht zu sagen, das prozedurale Paradigma ist schlecht, aber ich bekomme den Eindruck, Ihr Vorgesetzter erwartet, dass Sie schreiben "gute Objekt-orientierten code" und sind Sie wirklich wollen, um zu schreiben "gute prozeduralen code".
Gibt es viele gotchyas in Java, wenn Sie damit beginnen die Statik, die nicht immer sofort offensichtlich. Zum Beispiel, wenn Sie zwei Instanzen des Programms laufen in der gleichen VM, wird Sie shre die static-variable, die den Wert und die Sauerei mit dem Zustand der jeweils anderen? Oder was passiert, wenn du die Klasse erweitern, können Sie das überschreiben der statischen member? Ist dein VM der Speicher ausgeht, weil Sie wahnsinnige zahlen der Statik und der Speicher kann nicht zurückgefordert werden, für andere benötigt-Instanz Objekte?
Objekt-Lebensdauer:
Darüber hinaus Statik haben eine Lebensdauer, entspricht die gesamte Laufzeit des Programms. Das bedeutet, auch nachdem Sie fertig sind mit Ihrer Klasse, der Speicher von all den statischen Variablen, die nicht von der garbage Collection freigegeben. Wenn, zum Beispiel, anstatt, Sie machte Ihre Variablen nicht statisch und in Ihrer main () - Funktion, die Sie aus einer einzigen Instanz der Klasse, und dann fragte Ihre Klasse zum ausführen einer bestimmten Funktion 10.000 mal, sobald diese 10.000 Anrufe wurden gemacht, und löschen Sie die Verweise auf die einzige Instanz, die alle statischen Variablen werden könnte, Müll gesammelt und wiederverwendet.
Verhindert, dass bestimmte re-use:
Auch statische Methoden können nicht verwendet werden, um eine Schnittstelle implementieren, so dass statische Methoden können verhindern, dass bestimmte objektorientierte features als nutzbare.
Andere Optionen:
Wenn Effizienz das primäre Anliegen, kann es andere, bessere Weise zu lösen, die Geschwindigkeit problem als wenn nur der Vorteil von Aufruf wird in der Regel schneller als Schöpfung. Prüfen, ob die vorübergehende oder volatile-Modifizierer erforderlich sind überall. Zu erhalten die Fähigkeit, inline, eine Methode als final markiert, statt statisch. Die Parameter der Methode und anderen Variablen markiert werden kann-Finale zu ermöglichen, bestimmte compiler optimiazations basiert auf Annahmen über das, was ändern können die Variablen. Ein Instanz-Objekt wiederverwendet werden kann mehrere Male, anstatt eine neue Instanz zu erstellen jeder Zeit. Es kann compliler-Optimierungs-switches, die sollte aktiviert sein, damit die app im Allgemeinen. Vielleicht, das design sollte so aufgebaut sein, dass die 10.000 ausgeführt werden kann, die multi-threaded und nutzen von multi-Prozessor-cores. Wenn portablity ist kein Problem, vielleicht eine native-Methode erhalten Sie eine bessere Geschwindigkeit als Ihre Statik zu tun.
Wenn aus irgendeinem Grund Sie nicht möchten, dass mehrere Kopien eines Objekts, die singleton-design-Muster, hat Vorteile gegenüber der statischen Objekte, wie thread-Sicherheit (vorausgesetzt, Ihre singleton-codiert ist), das erlaubt eine lazy-Initialisierung, um das Objekt richtig initialisiert wurde, wenn es verwendet wird, sub-classing, Vorteile im Test-und refactoring-code, nicht zu erwähnen, wenn Sie irgendwann Ihre Meinung ändern und wollte nur eine Instanz eines Objekts, es ist VIEL einfacher, den code entfernen, um zu verhindern, dass doppelte Instanzen, als es ist, umgestalten, alle statischen Variablen code zu verwenden, Instanz-Variablen. Ich hatte zu tun, bevor, es ist nicht lustig, und Sie am Ende mit zu Bearbeiten viel mehr Klassen, die erhöht Ihre Gefahr der Einführung neuer Fehler...so viel besser, die Dinge so einzurichten "rechts" zum ersten mal, auch wenn es scheint, es hat seine Nachteile. Für mich ist die re-Arbeit erforderlich ist, sollten Sie sich entscheiden, die Straße hinunter, die Sie brauchen mehrere Kopien von etwas, das ist wohl einer der überzeugendsten Gründe für die Verwendung von Statik so selten wie möglich. Und deshalb würde ich auch nicht einverstanden mit Ihrer Aussage, dass die Statik reduzieren, Abhängigkeiten, ich denke, Sie werden am Ende mit code, der mehr gekoppelt, wenn Sie haben viel von Statik, die direkt aufgerufen werden können, sondern als ein Objekt, das "weiß, wie man etwas" auf sich selbst.
Obwohl das singleton selbst mag thread-sicher (z.B. durch die Verwendung
synchronized
Methoden), es bedeutet nicht, dass der aufrufende code ist frei von race conditions, die mit Bezug auf die singleton-Zustand.Auch die Statik nicht gegen das OOP-Paradigma. Viele OOP-Fanatiker wird Ihnen sagen, dass das Klasse ist ein Objekt, und die statische Methode ist eine Methode der Klasse Objekt, sondern als Instanzen. Dieses Phänomen ist weniger vorhanden in Java. Andere Sprachen, wie Python erlauben Sie die Verwendung von Klassen als Variablen und können Sie Zugriff auf statische Methoden als Methoden des Objekts.
+1 für die Erklärung der "object lifetime" von statischen Variablen.
Die Letzte Zeile des Dritten Absatzes Lesen sollten, alle Ihre non-static Variablen, wenn ich mich nicht Irre.
InformationsquelleAutor Jessica Brown
Böse ist ein subjektiver Begriff.
Du nicht kontrollierst, auf die Statik im Sinne der Schöpfung und der Zerstörung. Sie Leben auf Geheiß des Programms be-und entladen.
Da Statik, Leben in einem Raum, die alle threads nutzen möchten, Sie müssen gehen Sie durch die Zugriffskontrolle, die Sie zu bewältigen haben. Dies bedeutet, dass Programme mehr sind gekoppelt, und diese änderung ist schwieriger zu sagen und zu verwalten (wie J Skeet sagt). Dies führt zu Problemen mit der Isolierung ändern Wirkung und damit Einfluss darauf, wie die Prüfung gehandhabt wird.
Dies sind die zwei wichtigsten Fragen, die ich mit Ihnen haben.
InformationsquelleAutor Preet Sangha
Nicht. Globale Zustände sind nicht böse per se. Aber wir müssen sehen Ihre code zu sehen, wenn Sie es richtig. Es ist durchaus möglich, dass ein Neuling Missbrauch Globale Zustände; wie würde er Missstände, die jede Sprache verfügen.
Globale Zustände sind absolute Notwendigkeit. Wir können nicht vermeiden, globalen Staaten. Wir können nicht vermeiden, nachdenken über Globale Zustände. - Wenn wir kümmern uns zu verstehen, unsere Anwendung Semantik.
Menschen, die versuchen, um loszuwerden global Mitgliedstaaten aus Gründen, die unweigerlich am Ende mit einem viel komplexeren system - und globalen Staaten sind immer noch da, geschickt/idiotisch verkleidet, unter vielen Schichten von indirections; und wir haben immer noch Grund zum global-Staaten, nach dem Auspacken alle die indirections.
Wie der Frühling die Menschen, die aufwändig deklarieren von globalen Zuständen in xml und denke, irgendwie ist es überlegen.
@Jon Skeet
if I create a new instance of an object
jetzt haben Sie zwei Dinge auf Grund über - den Zustand innerhalb des Objekts, und der Zustand der Umwelt-hosting-Objekt.Dependency injection hat nichts zu tun mit der globalen Staat oder eine Globale Sichtbarkeit - auch der container selbst ist nicht global. Im Vergleich zu "normalen" code, die einzige zusätzliche Sache, eine container-verwaltete Objekt ist sichtbar, ist der container selbst. In der Tat, DI wird sehr allgemein verwendet, um das Singleton-Muster.
InformationsquelleAutor irreputable
Gibt es 2 Haupt-Probleme mit statischen Variablen:
Ich habe nicht die Thread-Sicherheit der Punkt, glaube ich, dass nichts ist thread-sicher, wenn Sie es so machen. Dies scheint nicht zu sein, in Bezug auf statische Dinge, an alle, bitte korrigieren Sie mich, wenn ich etwas fehlt.
Während es wahr ist, dass die thread-Sicherheit ist nicht ein Problem exklusiv für statische Variablen, denn von Ihrer definition Sie sind aufgerufen und von den verschiedenen Kontexten, Sie sind mehr beschneiden, um Sie
Ich verstehe, was du meinst, Ereignis, wenn die "verschiedenen Kontexten" ist nicht notwendigerweise gleich "anderen threads". Aber es ist wahr, dass die thread-safety muss oft berücksichtigt werden, mit statischen Ressourcen. Sie sollten erwägen, eine Klarstellung der Satz.
Es gelten Gewinde für die sichere Anwendung von statischen Ressourcen, zum Beispiel. private static final Logger LOG = Logger.getLogger(Foo.class); private static final AtomicInteger x = new AtomicInteger(0); So verstehe ich es, statische Zuordnungen von Ressourcen wie diese sind garantiert thread-sicher durch den class loader. Die Logger-Instanz ist oder nicht thread-sicher ist, unabhängig davon, wo ordnen Sie die Zeiger darauf. Den Status zu halten in der Statik ist wahrscheinlich nicht eine gute Idee, aber es gibt keinen Grund, es sollte nicht thread-safe.
InformationsquelleAutor sternr
Wenn Sie das 'static' Schlüsselwort ohne 'final' - Schlüsselwort, dies sollte ein signal sein, sorgfältig zu prüfen, Ihrem design. Auch das Vorhandensein einer 'final' ist kein freifahrtsschein, denn eine mutable static final object kann genauso gefährlich werden.
Ich würde schätzen irgendwo um die 85% der Zeit sehe ich bei einer 'statischen' ohne 'final', ist es FALSCH. Oft finde ich seltsam workarounds zu maskieren oder zu verstecken diese Probleme.
Erstellen Sie bitte keine statischen mutables. Vor Allem Sammlungen. Im Allgemeinen Sammlungen sollten initialisiert werden, wenn Ihre mit-Objekt ist initialisiert und sollte so ausgelegt sein, dass Sie zurückgesetzt oder vergessen, wenn Sie enthaltenden Objekt ist vergessen.
Mit Statik erstellen können sehr subtile bugs was zu " sustaining engineers Tagen Schmerzen. Ich weiß, denn ich habe beide erstellt und jagten diese Fehler.
Wenn Sie möchten mehr details, Lesen Sie bitte weiter...
Warum Nicht Mit Statik?
Gibt es viele Probleme mit der Statik, einschließlich schreiben und ausführen von tests, als auch die subtilen Fehler, die nicht sofort offensichtlich sind.
Code, die sich auf statische Objekte können nicht ohne weiteres Gerät getestet und die Statik kann nicht einfach verspottet (in der Regel).
Wenn Sie die Statik, es ist nicht möglich, tauschen Sie die Implementierung der Klasse aus, um zu testen, höhere level-Komponenten. Stellen Sie sich beispielsweise eine statische CustomerDAO zurückgibt, die Kunden-Objekte, die Lasten aus der Datenbank. Nun habe ich eine Klasse CustomerFilter, benötigt, um Zugriff auf Kunden-Objekte. Wenn CustomerDAO ist statisch, ich kann nicht schreiben, ein test für CustomerFilter, ohne zuerst initialisieren der Datenbank und füllen nützliche Informationen.
- Und Datenbank-Bevölkerung und die Initialisierung dauert eine lange Zeit. Und in meiner Erfahrung, Ihre DB-Initialisierung Rahmen wird im Laufe der Zeit ändern, d.h. Daten morph, und tests kann brechen. DH, stellen Sie sich vor Kunde 1 verwendet werden, ein VIP, aber die DB-Initialisierung Rahmen geändert, und jetzt Kunde 1 ist nicht mehr VIP, aber Ihr test war hart codiert zu laden Kunde 1...
Bessere Ansatz ist, ein Exemplar einer CustomerDAO, und übergeben es in die CustomerFilter, wenn es aufgebaut ist. (Ein noch besserer Ansatz wäre, um den Frühling oder andere Inversion of Control framework.
Sobald Sie dies tun, können Sie schnell zu verspotten oder die stub eine Alternative DAO in Ihrer CustomerFilterTest, so dass Sie mehr Kontrolle haben über den test,
Ohne die statische DAO, wird der test schneller (keine db-Initialisierung) und zuverlässiger (weil es nicht scheitern, wenn die db-Initialisierung code-änderungen). Zum Beispiel, in diesem Fall darauf, den Kunden 1 ist und wird immer sein ein VIP, soweit es den test angeht.
Der Durchführung Der Tests
Statik führen, dass ein echtes problem beim ausführen von Suiten von unit-tests zusammen (zum Beispiel mit Ihrem Continuous-Integration-server). Stellen Sie sich eine statische Zuordnung von Netzwerk-Socket-Objekte, bleibt offen von einem test zum anderen. Der erste test könnte einen Socket auf port 8080, aber Sie vergessen haben, löschen Sie die Anzeigen, Wann der test wird abgerissen. Wenn jetzt ein zweiter test startet, ist es wahrscheinlich zu Abstürzen, wenn es versucht, erstellen einen neuen Socket für port 8080, da der port noch belegt ist. Stellen Sie sich auch, dass Socket-Referenzen in Ihrer statischen Erhebung nicht entfernt werden, und (mit Ausnahme der WeakHashMap) sind nie berechtigt, Müll gesammelt, was zu einem Speicherverlust.
Dies ist ein over-generalized Beispiel, aber in großen Systemen tritt dieses problem DIE GANZE ZEIT. Denken die Menschen nicht von unit-tests starten und stoppen Sie Ihre software immer wieder in der gleichen JVM, aber es ist ein guter test für Ihre software-design, und wenn Sie Bestrebungen in Richtung hohe Verfügbarkeit, es ist etwas, das Sie brauchen, um sich bewusst sein.
Diese treten Häufig Probleme mit framework-Objekte, zum Beispiel, Ihren Zugriff auf die DB, caching, messaging-und logging-Ebenen. Wenn Sie mit Java EE oder einige best-of-breed-frameworks, die Sie wohl zu verwalten, eine Menge für Sie, aber wenn Sie wie ich sind Sie tun, mit einem legacy-system, Sie haben eine Menge von custom frameworks für den Zugriff auf diese Ebenen.
Wenn die system-Konfiguration, die für diese framework-Komponenten die änderungen zwischen unit tests und unit test framework nicht abreißen und neu erstellen der Komponenten, können diese änderungen nicht wirksam werden, und wenn ein test stützt sich auf diese änderungen, so werden Sie scheitern.
Sogar nicht-framework-Komponenten unterliegen diesem problem. Stellen Sie sich eine statische Karte genannt OpenOrders. Sie schreiben eine Prüfung, erstellt ein paar offene Aufträge und überprüft, um sicherzustellen, Sie sind alle im richtigen Zustand ist, dann ist der test beendet. Ein anderer Entwickler schreibt einen zweiten test was bringt die Aufträge, die es braucht in den OpenOrders Karte, dann behauptet die Anzahl der Bestellungen ist genau. Einzeln ausgeführt, diese tests würden beide gehen, aber wenn Sie laufen zusammen in einer suite, werden Sie scheitern.
Schlimmer Fehler sein könnte, basierend auf der Reihenfolge, in der die tests ausgeführt wurden.
In diesem Fall, durch die Vermeidung von Statik, vermeiden Sie die Gefahr von persistenten Daten in test-Instanzen und sorgt für eine höhere prüfsicherheit.
Subtile Bugs
Wenn Sie arbeiten in Umgebung mit hoher Verfügbarkeit, oder irgendwo threads können gestartet und gestoppt werden, die gleichen Bedenken, die oben erwähnt mit unit-test-Suiten, die angewendet werden können, wenn Ihr code ausgeführt wird, auf die Produktion als auch.
Beim Umgang mit threads, anstatt mit einem statischen Objekt, um Daten zu speichern, ist es besser, verwenden Sie ein Objekt initialisiert, während die thread-Start-phase. Auf diese Weise, jedes mal, wenn der thread gestartet wird, wird eine neue Instanz des Objekts (mit potenziell neuen Konfiguration) erstellt wird, und Sie vermeiden, die Daten aus einer Instanz von thread-Bluten durch auf die nächste Instanz.
Wenn ein thread stirbt, ein statisches Objekt nicht zurücksetzen oder Müll gesammelt. Stellen Sie sich vor Sie haben einen thread namens "EmailCustomers", und wenn es beginnt, füllt es einen statischen String-Sammlung mit einer Liste von E-Mail-Adressen, dann beginnt jede E-Mail-Adressen. Lets sagen, dass der thread unterbrochen oder abgebrochen, irgendwie, also hohe Verfügbarkeit-framework startet den thread. Dann, wenn der thread gestartet wird, lädt es die Liste der Kunden. Aber da wird die Kollektion statisch, es kann behalten Sie die Liste der E-Mail-Adressen aus der vorherigen Kollektion. Jetzt einige Kunden erhalten möglicherweise doppelte E-Mails.
Nebenbei: Static Final
Den Einsatz von "static final" ist tatsächlich das Java-äquivalent zu einem C #zu definieren, obwohl es die technische Umsetzung Unterschiede. Ein C/C++ #define ausgelagert der code durch den Präprozessor vor der Kompilierung. Ein Java "static final" wird am Ende Speicher auf dem stack. So, es ist mehr wie ein "static const" - variable in C++ als es ist, ein #define.
Zusammenfassung
Ich hoffe, dies hilft zu erklären, einige grundlegende Gründe, warum die Statik problematisch sind. Wenn Sie eine moderne Java-Frameworks wie Java EE oder Spring, etc, Sie können nicht auftreten, viele von diesen Situationen, aber wenn Sie arbeiten mit einem großen Körper von legacy-code, Sie können sich viel häufiger.
InformationsquelleAutor JBCP
Da niemand* hat es erwähnt: Parallelität. Statische Variablen können Sie überraschen, wenn Sie über mehrere threads Lesen und schreiben, um die statische variable. Dies ist Häufig in web-Anwendungen (z.B. ASP.NET und es kann dazu führen, dass einige ziemlich nervtötende bugs. Zum Beispiel, wenn Sie eine statische variable, die aktualisiert wird, von einer Seite, und die Seite angefordert wird, die von zwei Personen an "fast die gleiche Zeit", ein Benutzer kann das Ergebnis erwartet, von dem anderen Benutzer, oder noch schlimmer.
Ich hoffe, dass Sie bereit sind, zu sperren und Umgang mit Konflikten.
*Eigentlich Preet Sangha erwähnt.
Ich habe nicht ganz behaupten, aber für die Zwecke der Diskussion: die Trennung ist eine form des Schutzes. Thread-Zustände voneinander getrennt sind; globaler Zustand ist nicht. Eine Instanz-variable nicht müssen - Schutz, es sei denn, es ist ausdrücklich zwischen threads gemeinsam genutzt werden; eine statische variable ist immer teilen sich alle threads im Prozess.
Ich Wünsche thread-statische Variablen waren eher ein first-class-Konzept, da Sie sehr nützlich sein kann, für sicher, dass Informationen verfügbar sind, um einen umschlossenen Aufruf des Unterprogramms, ohne dass passieren, dass die Daten durch jede Schicht der Umhüllung. Zum Beispiel, wenn ein Objekt hatte, Methoden zu machen, um den thread gängigen Grafik-Kontext, und es wurden Methoden zum speichern/wiederherstellen der aktuellen Grafik-Kontext, mit diesen konnten Sie oft sauberer ist, als das übergeben der Grafik-Kontext durch jeden Aufruf der Methode.
InformationsquelleAutor Justin M. Keyes
Müssen Sie das Gleichgewicht der Notwendigkeit für die Kapselung der Daten in ein Objekt mit einem Zustand, versus der Notwendigkeit von einfach-computing das Ergebnis einer Funktion auf einige Daten.
So funktioniert die Kapselung. Bei großen Anwendungen, Statik neigen dazu, zu produzieren, spaghetti-code und nicht leicht erlauben, refactoring oder Test.
Die anderen Antworten auch gute Gründe gegen eine exzessive Verwendung von Statik.
InformationsquelleAutor Jérôme Verstrynge
Statische Variablen werden im Allgemeinen als schlecht angesehen, weil Sie repräsentieren Globale Zustand und sind daher viel schwieriger zu Grunde geht. Insbesondere, brechen Sie die Annahmen, die der Objekt-orientierten Programmierung. In der objektorientierten Programmierung, jedes Objekt hat seine eigenen Staat, vertreten durch die Instanz (nicht-statische) Variablen. Statische Variablen entsprechen dem Stand über Instanzen, die weit mehr sein kann, schwer unit testen. Dies ist vor allem, weil es schwieriger ist, zu isolieren änderungen an statischen Variablen zu einem einzigen test.
That being said, ist es wichtig, eine Unterscheidung zwischen regulären statischen Variablen (im Allgemeinen als schlecht), und der statischen Variablen (AKA Konstanten; nicht so schlimm).
"Statische Variablen entsprechen dem Stand über Instanzen hinweg" ist eine viel bessere Darstellungsweise. Ich habe bearbeitet meine Antwort.
InformationsquelleAutor Jack Edmonds
Zusammenfassend einige grundlegende Vorteile & Nachteile der Verwendung von Statischen Methoden in Java:
Vorteile:
Nachteile:
InformationsquelleAutor Virtual
Meiner Meinung nach ist es kaum jemals um Leistung, es geht um design. Ich denke nicht, dass der Einsatz von statischen Methoden als falsch adaptiert von der Verwendung von statischen Variablen (aber ich denke, Sie sind eigentlich reden über die Methode aufruft).
Es ist einfach darüber, wie Logik isolieren und ihm einen guten Platz. Manchmal rechtfertigt die Verwendung von statischen Methoden, von denen
java.lang.Math
ist ein gutes Beispiel. Ich denke, wenn du Namen, die meisten Ihrer KlassenXxxUtil
oderXxxhelper
du solltest besser überdenken, Ihr Entwurf.völlig einverstanden. Ich finde die OP ist nicht ganz klar, auf den Unterschied zwischen statischen Methoden und vars.
InformationsquelleAutor M Platvoet
Statische Variablen am wichtigsten ist, schafft problem mit der Sicherheit von Daten (jederzeit änderbar,kann jeder ändern,der direkte Zugriff ohne Objekt, etc.)
Für weitere Informationen Lesen Sie diese
Danke.
InformationsquelleAutor Anuj Patel
Es könnte vermutet werden, dass in den meisten Fällen, in denen Sie die Verwendung einer statischen variable, die Sie wirklich wollen, um mit der singleton-Muster.
Das problem mit der globalen Staaten ist, dass manchmal, was macht Sinn, wie global in einem einfacheren Kontext, muss ein bisschen flexibler in einem praktischen Kontext, und dies ist, wo die singleton-Muster wird nützlich.
InformationsquelleAutor Charles Goodwin
Scheint mir, dass Sie sich Fragen, über statische Variablen, aber Sie weisen auch darauf hin, statische Methoden in der Beispiele.
Statische Variablen sind nicht böse - Sie haben sich Ihre Annahme als Globale Variablen wie Konstanten in den meisten Fällen kombiniert mit der final-modifier, aber wie gesagt nicht übermäßig gebrauchen.
Statische Methoden aka utility-Methode. Es ist nicht in der Regel eine schlechte Praxis, um Sie zu benutzen, aber große Sorge, dass Sie vielleicht behindern testen.
Als ein Beispiel der großen java-Projekt, das eine Menge von Statik und Tue es rechts Weg, schauen Sie bitte auf Spielen! Rahmen. Es ist auch Diskussion über es in SO.
Statische Variablen/Methoden in Kombination mit statischen import sind ebenfalls weit verbreitet in Bibliotheken erleichtern, deklarative Programmierung in java wie: machen Sie es einfach oder Hamcrest. Es wäre nicht möglich, ohne eine Menge von statischen Variablen und Methoden.
Also statische Variablen (und Methoden) sind gut, aber verwenden Sie Sie mit bedacht!
InformationsquelleAutor cetnar
Gerade habe ich zusammengefasst einige der Punkte, die in den Antworten. Wenn Sie feststellen, etwas falsch ist bitte fühlen Sie sich frei, es zu korrigieren.
Skalierung: Wir haben genau eine Instanz in einer statischen variable pro JVM. Nehmen wir an, wir entwickeln eine Bibliothek-management-system, und wir beschlossen, den Namen des Buches eine statische variable, da es nur einen pro Buch. Aber wenn das system wächst und wir sind mit mehreren JVMs, dann wir haben nicht einen Weg, um herauszufinden, welches Buch wir tun?
Thread-Sicherheit: Beiden Instanz-Variablen und statischen Variablen kontrolliert werden müssen bei der Verwendung in multi-threaded-Umgebung. Aber bei einer Instanz-variable muss es nicht geschützt, es sei denn, es wird ausdrücklich zwischen threads gemeinsam genutzt werden, aber im Falle einer statischen Variablen ist es immer, die gemeinsam von allen threads im Prozess.
Testen: Obwohl testbare design nicht gleich zu einem guten design, aber wir selten beachten Sie ein gutes design, ist nicht überprüfbar. Als statische Variablen darstellen globalen Zustand und es wird sehr schwierig, um Sie zu testen.
Räsonieren über Staat:, Wenn ich eine neue Instanz einer Klasse, dann können wir Grund, über den Zustand dieser Instanz, aber wenn es mit statischen Variablen dann könnte es in jedem Staat. Warum? Da es möglich ist, dass die static-variable geändert wurde, von einigen anderen Instanz als statische variable genutzt wird-Instanzen.
Serialisierung: Serialisierung funktioniert auch nicht gut mit Ihnen.
Schöpfung und Zerstörung: Schöpfung und Zerstörung von statischen Variablen, die nicht kontrolliert werden können. In der Regel werden Sie erstellt und zerstört im Programm be-und entladen Zeit. Es bedeutet, dass Sie schlecht sind für die Verwaltung des Speichers und die Initialisierung zu starten.
Aber was ist, wenn wir Sie wirklich brauchen?
Aber manchmal können wir ein echtes Bedürfnis von Ihnen. Wenn wir wirklich das Gefühl die Notwendigkeit, viele statische Variablen, die in der Anwendung dann eine option ist die Anwendung der Singleton-Design-Muster, die alle diese Variablen. Oder wir erstellen ein Objekt haben, das diese statische variable und übergeben werden kann, um.
Auch wenn die statische variable gekennzeichnet ist final, es wird eine Konstante und der Wert, der zugewiesen wird, um es einmal kann nicht geändert werden. Es bedeutet, dass es uns retten wird, von den Problemen, die wir Gesicht durch seine Wandlungsfähigkeit.
InformationsquelleAutor i_am_zero
Noch ein anderer Grund: die zerbrechlichkeit.
Wenn Sie eine Klasse haben, die meisten Menschen erwarten zu können, erstellen Sie es und verwenden Sie es zu werden.
Können Sie Dokument-es ist nicht der Fall, oder gegen Sie zu schützen (singleton/factory pattern) - aber das ist zusätzliche Arbeit und damit zusätzliche Kosten.
Selbst dann, in einem großen Unternehmen, Chancen sind, wird jemand versuchen irgendwann Ihre Klasse ohne volle Aufmerksamkeit auf all die netten Kommentare oder in die Fabrik.
Wenn Sie die Verwendung von statischen Variablen viel, dass brechen wird. Fehler sind teuer.
Zwischen einem .0001% Verbesserung der performance und Robustheit zu ändern, indem potenziell ahnungslose Entwickler, die in vielen Fällen Robustheit ist die gute Wahl.
InformationsquelleAutor ptyx
Finde ich statische Variablen, die mehr bequem zu bedienen. Und ich nehme an, dass Sie effizient sind (Bitte korrigiert mich wenn ich falsch bin) weil, wenn ich hatte, um 10.000 Anrufe an eine Funktion innerhalb einer Klasse, ich wäre froh zu machen, die Methode, die statische und verwenden Sie eine einfache Klasse.methodCall() statt überladen den Arbeitsspeicher mit 10.000 Instanzen der Klasse, Richtig?
Ich sehen, was Sie denken, aber eine einfache Singleton-Muster wird das gleiche tun, ohne zu instanziieren 10 000 Objekte.
statische Methoden können verwendet werden, aber nur für Funktionen, die im Zusammenhang mit der Objekt-Domäne und nicht brauchen, oder verwenden Sie die internen Eigenschaften des Objekts.
ex:
Class.Instance
) ist kaum besser als eine statische variable. Es ist etwas mehr getestet, aber noch viel schlimmer, als Konstruktionen, bei denen Sie nur zufällig erstellen Sie eine einzelne Instanz anstatt Ihren code auf der Annahme es gibt nur eine.Nicht sicher, ich verstehe deinen Kommentar! ich war Reaktion auf die OP über das, was er sagte in Kursiv über instancing 10 000 Objekte. Ich verstehe nicht, warum vergleichen Sie ein singleton, und eine statische variable? Was verstehe ich von dem, was du geschrieben hast ist, dass Singleton ist schlechtes design...! Ich denke, dass ich missverstehen Sie, seit dem Spring Framework standardmäßig werden alle beans Singleton 😉
Eine klassische singleton(das hat
Class.Instance
) mit änderbarer Zustand ist schlechtes design IMO. In diesem Fall habe ich stark bevorzugen ein design, wo bekomme ich die singletons, die ich brauche, zu verwenden, übergeben Sie als parameter in die Klasse, die diese verwendet (in der Regel mit Hilfe von DI). Logisch unveränderlich classic singletons sind in Ordnung IMO.In Fall war es nicht klar, warum ein singleton-Klasse (singleton, wo die Klasse sicher ist ein single copy) auch nicht ohne weiteres prüfbar, es dicht zu Pärchen die Klasse Existenz der Programm-Lebenszyklus. Um es zu testen, müssen Sie sich an der Programm-Start und Herunterfahren, die Häufig Nebenwirkungen unwichtige zum testen der Klasse. Wenn es effektiv als singleton (eine Kopie in das Programm, nicht aber die Durchsetzung auf andere Weise), könnten Sie mehrere Kopien erstellen, an die test-Zeit ohne Programm, die überprüfung, dass Verhalten über die Klasse ist, wie-es-soll-werden für jedes Test-Szenario.
InformationsquelleAutor Cygnusx1
Dem Thema "Statik böse' ist eher ein Problem über den globalen Zustand. Der geeignete Zeitpunkt für eine variable statisch zu sein, wenn es nicht einmal mehr als einen Staat, IE-tools, die sollten zugänglich sein, indem das gesamte framework und immer wieder die gleichen Ergebnisse für die gleichen Methodenaufrufe sind nie "böse" als Statik. Zu Ihrem Kommentar:
Statik sind der ideale und effiziente Wahl für die Variablen/Klassen, die nicht immer ändern.
Das problem mit globalen Zustand ist die inhärente Inkonsistenz, die Sie erstellen können. Dokumentation über unit-tests oft dieses Problem zu beheben, da jeder Zeit gibt es einen globalen Zustand zugreifen können, die mehr als mehrere nicht zusammenhängende Objekte, Ihre unit-tests wird unvollständig sein, und nicht "Einheit" Maserung. Wie bereits in diesem Artikel über Globale Staats-und singletons, wenn Objekt A und B sind nicht (wie in einem nicht ausdrücklich Bezug zu einem anderen), dann sollten Sie nicht in der Lage sein, um Einfluss auf den Zustand B.
Gibt es einige Ausnahmen von dem Verbot globalen Zustand in guten code wie die Uhr. Die Zeit ist global, und--in gewissem Sinne--es ändert sich der Status von Objekten, ohne eine kodierte Beziehung.
InformationsquelleAutor Bryan Agee
Meine $.02 ist, dass einige dieser Antworten sind verwirrend, das Problem, anstatt zu sagen, "Statik bad" ich glaube, es ist besser zu reden, scoping und Instanzen.
Was ich sagen möchte ist, dass eine statische ist eine "Klasse" Variablen - es represenst ein Wert, der geteilt wird von allen Instanzen der Klasse. Normalerweise sollte eingeschränkt werden, wie gut (geschützt oder privat für die Klasse und Ihre Instanzen).
Wenn Sie planen, setzen Klasse-level-Verhalten, um es und setzen Sie es keinen anderen code, dann ein singleton kann eine bessere Lösung zur Unterstützung von änderungen in der Zukunft (wie @Jessica vorgeschlagen). Dies ist, weil Sie über Schnittstellen können an die Instanz/singleton-Ebene in einer Weise, die Sie nicht verwenden können, die auf Klassen-Ebene - insbesondere bei der Vererbung.
Einige Gedanken, warum ich denke, dass einige Aspekte, andere Antworten sind nicht der Kern der Frage...
Statik sind nicht "global". In Java-scoping separat gesteuert von statischen/Instanz.
Parallelität ist nicht weniger gefährlich für die Statik als Instanz-Methoden. Es ist immer noch Staat, der geschützt werden muss. Sicher können Sie über 1000 Instanzen, die mit einer Instanz-variable jedes und nur eine statische variable, aber wenn der code Zugriff auf entweder ist das nicht geschrieben in einer threadsicheren Weise sind Sie noch geschraubt, es kann nur etwas länger dauern, für Sie zu verwirklichen.
Verwaltung von life-cycle-ist ein Interessantes argument, aber ich denke, es ist eine weniger wichtige. Ich sehe nicht, warum die schwerer zu verwalten ein paar Klasse Methoden wie init()/clear () - als die Erschaffung und Zerstörung einer singleton-Instanz. In der Tat, man könnte sagen, dass ein singleton ist ein wenig komplizierter, wegen der GC.
PS, In Sachen Smalltalk, viele seiner Dialekte haben Klassenvariablen, aber in Smalltalk Klassen sind eigentlich Instanzen der Metaklasse, also Sie sind wirklich sind Variablen, die auf die Metaklasse instance. Dennoch würde ich gelten die gleiche Faustregel. Wenn Sie verwendet werden für die gemeinsame Staat über den Instanzen dann auf ok. Wenn Sie Unterstützung von öffentlichen Funktionen, die Sie sollten sich auf ein Singleton. Seufz, ich sicher nicht vermissen Smalltalk....
InformationsquelleAutor studgeek
Es ist nichts falsch mit statischen Variablen per se. Es ist nur die Java-syntax kaputt. Jede Java-Klasse definiert zwei Strukturen - ein singleton-Objekt kapselt die statischen Variablen, und eine Instanz. Definieren Sie beide in der gleichen Quelle-block ist das pure böse, und die Ergebnisse in einem code, der ist schwer zu Lesen. Scala hat Recht.
InformationsquelleAutor Zdeněk Pavlas
a) Grund zu Programmen.
Wenn Sie eine kleine bis mittelgroße-Programm, bei dem die statische variable Global ist.foo zugegriffen wird, wird der Anruf, es kommt normalerweise aus dem nichts - es ist kein Pfad ist, und somit keine Zeitachse, wie die variable kommt an die Stelle, wo es verwendet wird. Nun, wie kann ich wissen, wer es eingestellt werden, um den tatsächlichen Wert? Wie kann ich wissen, was passiert, wenn ich ändern Sie es jetzt? Ich habe grep über die gesamte source, um alle zu sammeln zugreift, um zu wissen, was Los ist.
Wenn Sie wissen, wie Sie verwenden es, weil Sie gerade schrieb, der code, das problem ist unsichtbar, aber wenn Sie versuchen zu verstehen, fremden code zu verstehen.
b) sind Sie wirklich nur benötigen?
Statische Variablen, die oft verhindern, dass mehrere Programme der gleichen Art laufen in derselben JVM mit unterschiedlichen Werten. Sie haben oft nicht vorhersehen Verwendungen, in denen mehr als eine Instanz des Programms ist nützlich, aber wenn es sich entwickelt, oder ob es nützlich für andere, Sie könnten Situationen auftreten, wo Sie beginnen möchten, sich mehr als eine Instanz des Programms.
Nur mehr oder weniger nutzlosen code, die nicht verwendet werden, die von vielen Personen über längere Zeit in einen intensiven Weg gehen könnte, auch mit statischen Variablen.
InformationsquelleAutor user unknown
Gibt es zwei wichtigsten Fragen in deinem post.
Erste, über statische Variablen.
Statische Variablen sind completelly unnecesary und es ist zu verwenden, können leicht umfahren werden. In OOP languajes im Allgemeinen, und in Java particularlly, die Parameter der Funktion sind vom Austragungsort ab, die durch Verweis, dies ist zu sagen, wenn Sie ein Objekt übergeben, um einen funciont, übergeben Sie einen Zeiger auf das Objekt, so dass Sie nicht brauchen, um zu definieren statische Variablen da übergeben Sie einen Zeiger auf das Objekt, um jeden Bereich, der braucht diese Informationen. Auch wenn dies bedeutet, dass yo wird füllen Sie Ihre Speicher mit Zeigern, das wird nicht notwendig, stellen eine schlechte Leistung, weil tatsächliche Speicher-pagging-Systeme sind optimiert, um Griff mit diesem, und behalten Sie in Erinnerung, die Seiten verwiesen wird, durch die Hinweise, die Sie übergeben, um den neuen Bereich; die Verwendung von statischen Variablen kann das system zum laden der Speicher-Seite, wo Sie werden gespeichert, wenn Sie erreicht werden müssen (das wird passieren, wenn die Seite wurde nicht der Zugang in eine lange Zeit). Eine gute Praxis ist, um alle, die statische stuf zusammen in einer kleinen "Konfiguration clases", dies wird sicherstellen, dass das system stellt es alle in den gleichen Speicher-Seite.
Zweiten, über statische Methoden.
Statische Methoden sind nicht so schlecht, aber Sie können schnell die Leistung verringern. Denken Sie beispielsweise an eine Methode vergleicht zwei Objekte einer Klasse, und gibt einen Wert zurück, der angibt, welche Objekte, die größer ist (Vergleich typische Methode) mit dieser Methode kann statisch sein oder nicht, aber wenn die Berufung auf Sie die nicht statische form wird mehr eficient da Sie zu lösen haben, nur zwei Referenzen (eine für jedes Objekt) Gesicht zu den drei Referenzen, die zu lösen, die statische version der gleichen Methode (einen für die Klasse plus zwei, eine für jedes Objekt). Aber wie gesagt, das ist nicht so schlimm, wenn wir einen Blick auf die Math-Klasse, finden wir eine Menge von mathematischen Funktionen definiert als statische Methoden. Das ist wirklich mehr eficient, als wenn Sie auf alle diese Methoden in der Klasse definieren die zahlen, weil die meisten von Ihnen sind rarelly verwendet und inklusive aller von Ihnen in die Reihe Klasse wird verursachen, dass die Klasse sehr Komplex und verbrauchen eine Menge von Ressourcen unnecesarilly.
In concluson: Vermeiden Sie die Verwendung von statischen Variablen und finden Sie die richtigen performance-Gleichgewicht beim Umgang mit statischen oder nicht-statischen Methoden.
PS: Sorry für mein Englisch.
InformationsquelleAutor jrodriguez
alles (können:) haben Ihren Zweck, wenn Sie Bündel von Fäden, die muss share/cache Daten und auch alle zugänglichen Speicher (so dass Sie nicht aufgeteilt in Kontexten innerhalb einer JVM) die statische ist die beste Wahl,
-> natürlich können Sie nicht zwingen, nur ein Beispiel, aber warum?
ich finde einige Kommentare in diesem thread das böse, nicht der Statik 😉
InformationsquelleAutor tomasb
Alle der oben genannten Antworten zeigen, warum die Statik schlecht sind. Der Grund, Sie sind böse ist, denn es gibt den falschen Eindruck, dass Sie das schreiben der Objekt-orientierten code, wenn in der Tat sind Sie nicht.
Das ist einfach nur böse.
Ja, es macht es besser, weil es macht es mehr überschaubar in der Zukunft leichter zu verstehen und eindeutiger.
Warum ist es böse, nicht zu schreiben OO code machen? und warum nicht Bjarne Stroustrup mit Ihnen einverstanden? um nur eins zu nennen ...
Ich wollte nicht sagen, seine böse nicht zu schreiben OO code. Ich sagte Ihr böse zu denken, dass Sie schriftlich OO-code, wenn alles, was Sie unkenntlichmachen globals hinter statischen Methoden und Eigenschaften. Bitte Lesen Sie nochmals was ich geschrieben habe.
InformationsquelleAutor blockhead
Statische Variablen sind nicht gut noch böse. Sie repräsentieren Attribute, die beschreiben, die ganze Klasse und nicht eine bestimmte Instanz. Wenn Sie brauchen, um einen Zähler für alle Instanzen einer bestimmten Klasse, die eine statische variable wäre der richtige Ort, um halten Sie den Wert.
Probleme angezeigt, wenn Sie versuchen, verwenden Sie statische Variablen für holding-Instanz verknüpften Werte.
InformationsquelleAutor Andres
Es gibt viele gute Antworten hier, indem es,
Speicher:
Statische Variablen Leben so lange wie der class-loader Leben[im Allgemeinen bis VM stirbt], dies ist aber nur im Falle von bulk-Objekte/Referenzen gespeichert als statisch.
Modularisierung:
berücksichtigen Sie Konzepte wie IOC, dependencyInjection, proxy etc.. Alle sind vollkommen gegen fest-Kupplung/statische Implementierungen.
Anderen Con ' s: Thread-Sicherheit, Testbarkeit
InformationsquelleAutor 147.3k
Denken, dass, wenn Sie eine Anwendung mit vielen Benutzern, und Sie haben definieren einer statischen form, wird jeder Benutzer ändern in allen anderen Formen von anderen Benutzern zu.
InformationsquelleAutor seinta
Ich denke, dass übermäßige Verwendung von globalen Variablen mit dem Schlüsselwort static wird, führt auch zu Speicher Leckage an einem gewissen Punkt in etwa in der ge
InformationsquelleAutor Rahul Anand
Aus meiner Sicht
static
variable sollte nur nur Lesen Daten oder Variablen erstellt durch Konvention.Zum Beispiel haben wir ein ui von einem Projekt, und wir haben eine Liste von Ländern, Sprachen, Benutzer, Rollen, etc. Und wir haben die Klasse zu organisieren, diese Daten. wir sind absolut sicher, dass app wird nicht funktionieren ohne diesen Listen. also das erste, das wir tun, auf app-init ist, überprüfen Sie diese Liste für updates und immer diese Liste aus der api (wenn nötig). Also wir sind damit einverstanden, dass diese Daten "immer" in-app. Es ist praktisch nur-lese-Daten, so brauchen wir nicht zu kümmern, es ist Status - denken über diesen Fall, die wir wirklich nicht wollen, um eine Menge von Instanzen, die diese Daten - in diesem Fall sieht ein perfekter Kandidat zu sein, statische.
InformationsquelleAutor qiAlex