Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Mich würde interessieren in welchen Fällen es sinnvoll ist Objekte die definitiv nur einmal im Programm vorkommen trotzdem nicht statisch zu machen. Oder sollte man das gar nicht machen? Bis jetzt habe ich static relativ rar verwendet, auch wenn die entsprechenden Elemente nur einmal auftauchen. Allerdings merke ich mehr und mehr das es oft einfach unpraktisch ist.
Es gibt schon nen paar Fälle wo man static einsetzt, auszugsweise mal:
- Utility Klassen: beispielsweise Math
- Factory method
(- Singleton, kann man über ne statische Variable realisieren)
In der Regel komm man aber auch sehr gut ohne static aus, vor allem am Anfang.
Naja es ist einfacher zu beantworten wann man static verwendet als wann man es nicht verwenden sollte.
Es gibt keine direkten Nachteile wenn du static verwendest und der Code danach immernoch funktioniert. Persöhnlich würde ich sogar behaupten, dass der static-Aufruf schneller und effizienter ist als eine Objektorientierte Variante. (Wenn auch nicht offensichtlich für den Anwender sichtbar)
Statische Klassen finden häufig Verwendung für oft genutzte Codeteile. Im Grunde als ob man ein Stück Code abspeichert und überall im Code einfügen kann/einfügt.
(Bsp. Math.[etc.] )
Oder bei diversen Daten die für das gesammte Programm definiert werden müssen.
Weil evt. fast jeder Programmteil uneingeschränkt Zugriff auf die gleichen Daten haben muss. (Bsp. LookAndFeel)
Jedoch nur zum Zugriff. Wenn die Daten auch verändert werden sollen im Nachhinein, so sollte man dann doch zu einer Objektorientierten Variante greifen.
Mich würde interessieren in welchen Fällen es sinnvoll ist Objekte die definitiv nur einmal im Programm vorkommen trotzdem nicht statisch zu machen. Oder sollte man das gar nicht machen?
Zunächst einmal kann man Objekte nicht statisch machen ;-) Man kann auf Objekte referenzierende Variablen statisch deklarieren.
Mir fällt aber gerade kein Fall ein bei dem das sinnvoll sein könnte - wenn sowas nicht sogar auf einen Designfehler hindeutet.
Sinnvoll kann es sein Hilfsmethoden statisch zu deklarieren, siehe z.B. die Klasse Math oder Variablen auf Primitive + Strings, die dann als Identifier/Schlüssel dienen z.B JFrame.EXIT_ON_CLOSE
Und ist es dann sinnvoll Objekte die definitiv nur einmal existieren sollen immer als Singleton zu implementieren? aber generell nicht unbedingt Methoden und Felder statisch zu machen?
so pauschal schwer zu beantworten. Ein Singleton hat Vor- und Nachteile, die gilt es abzuwägen und auf Relevanz für den eigenen Anwendungsfall zu prüfen.
Programmierst du für dich oder für mehrere?
Im Beruf kann es dazu kommen, dass mithilfe von Singleton bestimmte menschliche aber auch maschinelle (Die wiederum selber vom Menschen stammen ) Fehler und Anwendungsweisen zu verhindern.
Hier kommt es auf den Fall an.
Wenn du jedoch Hobbyprogrammierer bist, braucht dich das eig. wenig zu stören.
Hier würde ich raten, sich einfach nicht damit aufzuhalten. Schlussendlich gibt es hier keinen merklichen Unterschied.
Programmiere für mich als Hobby. Aber evtl. auch als berufliche Perspektive.
Mir ist nur aufgefallen dass es mich relativ häufig stört Objekte miteinander bekannt zumachen. Vor allem wenn das Projekt ein bisschen größer wird.
static und GarbageCollection schließen sich nahezu aus.
Ein Objekt das mit einer static Varible referenziert wird, besitzt immer eine Referenz und wird daher nicht vom GarbageCollector erfasst, was unter umständen zu einem Memory-Leak führen kann.
Mit static und Methoden, kann man sich auch sehr leicht Vererbung und Polymorphie verbauen.
Mir ist nur aufgefallen dass es mich relativ häufig stört Objekte miteinander bekannt zumachen. Vor allem wenn das Projekt ein bisschen größer wird.
Persöhnlich würde ich sogar behaupten, dass der static-Aufruf schneller und effizienter ist als eine Objektorientierte Variante. (Wenn auch nicht offensichtlich für den Anwender sichtbar)
persönlich bin ich überhaupt kein fan von static
das einzige static was es in meinen codes gibt ist in der regel nur main
allerdings fällt mir auf anhieb auch nur kram ein bei dem sinn macht zu erklären wann sich static lohnt ... ansatt zu versuchen zu argumentieren wo es sich nicht lohnt ... um mal auf "Network"s post einzugehen
zum beispiel konstanten > static final
in wie weit man hier public/protected/private verwendet hängt vom anwendungsfall ab ... aber man sollte natürlich den conventions entsprechend den scope immer so klein wie möglich halten
dann würden mir noch utility- und factory-klassen einfallen
utility im sinne von Math ... also einfach nur eine art von code-sammlung um halt code-duplizierung zu vermeiden
factories sollten denke ich klar sein ...
ob sich static in singletons eignet ... hmm ...
habe leider noch nicht viel mit singletons gemacht und bin daher eher geteilter meinung
ich kenne zwar einige singleton-factories ... aber in der regel hat man bei diesen noch die auswahl zwischen einer statischen "default" instanz ... und halt "normalen" instanzen ...
aber ich denke singleton ist eher ein thema für sich
wie du siehst : es gibt schon dinge wo es halt sinn macht static zu verwenden ... aber da java nun mal eine objekt orientierte sprache ist sehen static's meiner ansicht nach eher nach imperativer programmierung aus ...
Singleton? Hmm, hab ich als Anfänger damals auch gedacht... Ein statisches Objekt für die Settings, eines für ... Inzwischen hab ich gemerkt, dass man auch ohne statisch deklarierte Objekte ganz hübschen Code schreiben kann. Aber wie man merkt schlagen sich anfänglich viele mit diesem Problem rum, weil sie es schlicht nicht besser wissen.
Ein weiterführendes Stichwort zu diesem Thema wär DI Denn es ist mir verständlich, dass man nicht immer alle Objekte überall rumschleifen will
Ich wunder mich grad, wieso hier Factories und static in einem Zusammenhang genannt werden. Das wuerd ich niemals machen. Wenn ich das richtig verstehe, meint ihr sowas:
Java:
public interface Product {}
public class ProductA implements Product {..}
public class ProductB implements Product {..}
public class Factory {
public static Product createProduct( int type ) {
switch(type){
case 0: return new ProductA();
case 1: return new ProductB();
default: throw new IllegalArgumentException();
}
}
}
Das Problem ist hier, man hat keine vernuenftige Chance die createProduct Methode so anzupassen (durch Vererbung), dass sie in den Tests eine Instanz von z.B. [c]TestProductA[/c] zurueckliefert. Fuer gute (Unit-)tests ist das aber extrem wichtig. Deshalb, niemals Factory Methoden static machen!
Persöhnlich würde ich sogar behaupten, dass der static-Aufruf schneller und effizienter ist als eine Objektorientierte Variante. (Wenn auch nicht offensichtlich für den Anwender sichtbar)
Da möchte ich doch ernsthaft mal ein vollständige Anwendung sehen die mit static geschrieben ist und eine ohne und dann bitte einen sauberen Vergleich....Behauptungen kann man viele aufstellen...das Problem dabei ist...sie zu belegen...
Höre ich sehr oft...das ist schneller/braucht weniger Speicher.. etc.
Das Problem ist nämlich nicht die Performance sondern die Lesbarkeit...von Code...Sources Code wird von Menschen gelesen....
Statische Klassen finden häufig Verwendung für oft genutzte Codeteile. Im Grunde als ob man ein Stück Code abspeichert und überall im Code einfügen kann/einfügt.
Das hat dann nichts mehr mit einer Klasse zu tun sondern mit einer Funktion...(siehe auch Math.[etc.] ). In Java gibt es nun mal keine Möglichkeit Funktionen OHNE Klasse zu definieren. Das hat aber nichts damit zu tun, dass das dann auch eine Klasse ist sondern die Klasse dient hierbei nur als "syntaktischer Kontainer"...
Das was Du dort beschreibst hat man früher Makro genannt (gab es schon in sog. Makro-Assemblern)...
Meine Erfahrung nach ist eine statische Methode oft der Ausdruck von fehlender Überlegen bzgl. der Verantwortlichkeit von Code...sprich man denkt nicht genug darüber nach wo der Code für eine Methode hingehört...dann wird halt schnell mal eine Klasse mit einer static-Methode gemacht..ist ja einfacher...
Wenn Du so eine Klasse bzw. static verwendest geht das auf dauer in die Hose...OO Prinzipien sind besser ...Es gibt aber durchaus Anwendungsfälle wo das nicht funktioniert, da sollte man dann aber auch eher auf eine funktionale Sprache setzen....
Oder bei diversen Daten die für das gesammte Programm definiert werden müssen.Weil evt. fast jeder Programmteil uneingeschränkt Zugriff auf die gleichen Daten haben muss. (Bsp. LookAndFeel)
Man kann fast alle Anwendungen von static vermeiden einfach durch Nutzung von Dependency Injection...Damit kann man sogar Konstanten erzeugen...wobei ich durchaus der Meinung bin dass man bei Konstanten sich eventuell auf eine static einlassen kann...aber ich würde da noch eher zu einem ENUM Tendieren...hängt aber vom Anwendungsfall ab...
Meine Erfahrung nach ist eine statische Methode oft der Ausdruck von fehlender Überlegen bzgl. der Verantwortlichkeit von Code...sprich man denkt nicht genug darüber nach wo der Code für eine Methode hingehört...dann wird halt schnell mal eine Klasse mit einer static-Methode gemacht..ist ja einfacher...
Das sieht man z.B. bei [c]Collections#sort()[/c]. Da würde ich lieber [c]List.sort()[/c] verwenden, aber aus irgendeinem Grund wurde da lieber die Util-Klasse [c]Collections[/c] erschaffen. Aber AFAIK kommt mit irgendeiner Javaversion dann auch noch [c]sort()[/c] in den jeweiligen Collections selbst (auch wenn es nur einen Durchlauferhitzer für [c]Collections#sort()[/c] sein würde).
Um mal eine Lanze für static zu brechen: Fields sollten praktisch nie static sein. Methoden sollten IMHO immer static sein, wenn sie das ohne Verrenkungen sein können. Wenn man eine Methode hat, die nicht mit irgendeinem Zustand assoziiert ist, gibt es keinen Grund, sie nicht static zu machen. In bezug auf Testbarkeit sehe ich da kein so gravierendes Problem. Eine static Methode in eine Objektmethode einzuwickeln ist einfach, umgekehrt u.U. unmöglich. Dazu kommen Dinge wie die "default"-Implementierungen von Interfacemethoden in Java8 mit statischen Methoden.
Da möchte ich doch ernsthaft mal ein vollständige Anwendung sehen die mit static geschrieben ist und eine ohne und dann bitte einen sauberen Vergleich....Behauptungen kann man viele aufstellen...das Problem dabei ist...sie zu belegen...
Höre ich sehr oft...das ist schneller/braucht weniger Speicher.. etc.
Das Problem ist nämlich nicht die Performance sondern die Lesbarkeit...von Code...Sources Code wird von Menschen gelesen....
Ich hatte schon befürchtet, dass der Teil hier missverstanden wird. Mit "schneller und effizienter" meinte ich nicht den Code bzw. das Programm. Darüber kann man viel streiten und auf ein paar Ticks mehr oder weniger kommt es auch nicht an, da eben meist C-Code für Mikroprozessoren verwendet wird und dergleichen.
Und bitte ich will jetzt keine Diskussionen hören, dass es solche Varianten auch gibt.
Viel eher ging es um die Entwicklung an sich. Da so manche komplizierte Teile (In einem Flussdiagramm sieht man sehr schön den Unterschied) einfach wegfallen was das "aneinander bekanntmachen" angeht.
Und wenn der Code unübersichtlicher wird, dann ist das die Schuld des Programmierers und nicht von "static". Bei unzureichender Dokumentation ist die Unübersichtlichkeit nicht größer wie wenn man diese Methode oo aufruft. Sieht schlussendlich fast genau gleich aus im Code. Egal ob man jetzt "math.sin(i)" oder "Math.sin(i)" im Code stehen hat.
Und für static Methoden sollte nunmal auch gelten, dass man nicht jeden x-beliebigen Code-Bruchteil in eine eigene Methode verfrachtet.
Du versteckst mit den ganzen statics aber Abhängigkeiten. Und das macht den Code sehr unschön zu lesen. Besonders wenn dann deine statischen Aufrufe ihrerseits wieder irgendwelche statischen Methoden aufrufen. Das mag vllt dein Flussdiagramm aufhübschen, aber den Code machts undurchsichtig.
Zum Thema testen:
Stell dir vor du hast ne Klasse Configuration die statische Methoden zum setzen und lesen von Werten hat. Diese Werte werden dann von der Klasse bspw. in ner Datenbank persistiert.
Jetzt willst du ja beim Testen nicht jedesmal hunderte DB Zugriffe haben, sondern die Configuration gegen eine TestConfiguration austauschen die ihre Werte nur im Speicher hält (reicht ja für deine Tests vollkommen aus). Dann bekommst du das nicht hin wenn du an allen Ecken und Enden irgendwelche statischen Aufrufe auf der Configuration machst.
Wenn du die Abhängigkeit explizit übergibst dann könnte das so aussehen:
Java:
// Im normalen Programm
Controller c = new Controller(new Configuration());
// Bei deinen Tests
Controller c = new Controller(new TestConfiguration());
Noch schöner wirds wenn du dann noch nen DI Framework einsetzt
Ein Programm wie man so, oder so ähnlich sehr sehr häufig antrifft.
Java:
class Foo{
void bar(){
System.out.println("baz");
}
}
Und schon hat man den Salat, wenn man das Testen möchte.
Java:
class TestFoo{
@Test
void NotTestBar(){
new Foo().bar();
hopefullySucceeded();
}
}
Und das nur, weil man das static out verwendet hat.
Java:
class TestFoo{
PrintStream original;
ByteArrayOutputStream baos;
@Before
void doBefore(){
original = System.out;
baos = new ByteArrayOutputStream();
PrintStream test = new PrintStream(baos);
System.setOut(test);
}
@After
void doAfter(){
System.out = original;
}
@Test
void testBar(){
new Foo().bar();
assertEquals("baz", baos.toString());
}
}
Das sollte zwar funktionieren, aber wirklich schön, finde ich das nicht.
Punkt 1, wäre State in der Testklasse.
Punkt 2, der "Zwang" aufzuräumen in einem doAfter().
Verzichtet man nun auf das static, kann man sich den PrintStream z.B. auch übergeben lassen.
Java:
class Foo{
private PrintStream out;
public Foo(PrintStream out){
this.out = out;
}
void bar(){
out.println("baz");
}
}
Auf den Konstruktor kann man gegebenenfalls auch verzichten, wenn PrintStream mit einem @Inject annotiert wird.
Beim Testen muß man sich immer noch den PrintStream bauen, und der Klasse übergeben, man kann aber das Aufräumen dem GarbageCollector überlassen und hat die Gefahr gebannt, sich irgendwelche Seiteneffekte einzufangen.
Java:
class TestFoo{
@Test
void testBar(){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream test = new PrintStream(baos);
new Foo(test).bar();
assertEquals("baz", baos.toString());
}
}
Es sollte jetzt aber nicht irgendjemand kommen ... und behaupten, ich würde behaupten, man solle nicht mehr ...System.out.println(); verwenden, weil das böse ist ... und wie Sinnlos eine komplett Schwarze Konsolenanwendung ist.
Ich finde System.out soll man an die jeweiligen Stellen übergeben, an denen es verwendet wird. Also new Foo(System.out); ist ok. Ein Aufruf von System.out.println("some text"); sollte schon fragwürdig sein.
Erst recht in Anwendungen bei denen nicht die Konsole das Hauptausgabemedium ist (Dort sind Logger die bessere Wahl).
Ein weiteres Beispiel, das in diese Kategorie passt ist System.currentTimeMillis();.
Es ist nicht die Methode die schlecht ist. Es ist die Verwendung dieser Methode. Und zwar die Direkte Verwendung. Wenn ich Beispielsweise eine Stopuhr programmiere, dann habe ich in der Regel zwei Aufrufe von System.currentTimeMillis(); Wenn der Aufruf nun direkt ist und ein Test besagt, dass die Anzeige daraufhin getestet werden soll eine Stopzeit von 2 Stunden anzuzeigen, dann läuft ein Test 2 Stunden lang. Das möchte keiner!. Wenn der Aufruf allerdings in einem Object gekappselt ist, dann kann dieses durch ein Testobjekt ersezt werden, dass bei zwei, auch in kurzer Zeit aufeinanderfolgenden Aufrufen, eine vorher eingestellte Zeitdifferenz zurückgegeben werden.
Viel eher ging es um die Entwicklung an sich. Da so manche komplizierte Teile (In einem Flussdiagramm sieht man sehr schön den Unterschied) einfach wegfallen was das "aneinander bekanntmachen" angeht.
Wenn du anscheinend nicht sehr gerne objektorientiert programmierst, warum dann Java :bahnhof: ?
Abgesehen davon wurde das Stichwort "Dependency Injection" bereits genannt, was das "Problem" der vielen Abhängigkeiten vereinfacht.
Na da hab ich ja ein sensibles Thema angestochert auf der falschen Seiten ^^
Entweder übertreibt ihr ein bischen oder ich war in meiner Aussage zu extrem.
Besonderst fühle ich mich teilweise missverstanden. Insbesondere was den Post über mir angeht. Ich will mich hier auch nicht rechtfertigen und das muss ich auch nicht
Der Mensch ist zum lernen da weshalb ich mir einfach mal erlaube in diesem Thread eine eigene Frage zu stellen. Ihr würdet mir sehr helfen, da sich in den letzten Jahren kein Kollege kein übgreifender Partner über meinen Stil beschwert hat
Ich muss eine Datenbankklasse schreiben. Bis jetzt müssen ca. 23 verschiedene Klassen darauf zugreifen. Evt. Mehr oder weniger folgend.
Die Klasse hat die Funktion bestimmte Daten zu laden Wichtig ist jedoch, dass die Daten nur ein einziges mal gelesen werden.
Also dachte ich mir ich mache diese Funktion static sowie diverse benötigte booleans die in derFunktion verwendet werden. So kann ich davon ausgehen, dass auf die Daten nur ein einziges mal zugegriffen wird indem ich d Variablen static habe und die static-Methode sorgt gleichzeitig dafür dass ich mich nicht darum kümmern muss, die Datenklasse jeder Klasse einzeln vorzustellen, was natürlich sehr bequem ist. Angemerkt sei, dass ein 2. Zugriff auf die Datenbank zu einem sofortigen instabilen Zustand führt -> Hardwaretechnisch bestimmt.
Weitere Anmerkung: Bis jetzt ist es die einzige Non-Sun/Oracle static Klasse die in dem bis jetzt erst 50+ Klassenprogramm geschrieben wurde- nur um diverse Missverständnisse für manche vorige Poster auszulöschen nur static-Methoden zu schreiben.
Wie würden die Anti-Staticer das handhaben?
Vieleicht kann ich ja was lernen
hmm ... nicht wirklich tolles beispiel ... denn das lässt sich deutlich eleganter lösen
1) OOP
es ist gerade sinn und zweck von OOP das eben jedes object was auf die datenbankverbindung zugreifen will eine referenz auf den datenbankhandler bekommt ... static wäre hier eher imperativ ... und damit eben nicht im sinne von java
2) singleton
wenn es wichtig ist das nur eine instanz vorhanden ist *denn viel mehr ist das static-gewirr auch nicht ... nur eben ohne object-reference* dann bietet sich das singleton pattern an ...
das einzige was ich hier wenn überhaupt static machen würde wäre eine vorgeschaltete factory ...
3) MVC
auch zu erwähnen wäre gerade in deinem beispiel das MVC pattern ...
der datenbankhandler wäre dann in dem fall der controller
die daten selbst *welcher hierfür wiederum in eigenen objekten / klassen liegen müssten* das model
und alles was dann von außen über den controller auf das model zugreift der view ...
du siehst also das gerade für dein beispiel gerade mal genau EIN static nötig wäre ... und das wäre auch nur wenn man wirklich ein singleton mit einer static-factory verwenden würde ... alles andere wäre "richtiges" OOP und braucht damit kein static
ich persönlich habe ja schon meinen standpunkt zu "static" dargelegt ...
wollte dir nur mal eine anwendungsmöglichkeit auf dein gegebenes beispiel geben
Network, aber - wie schon zig mal gesagt - gerade für so was lohnt sich DI. Z.B. mit Spring eine Instanz dieser Datenbank erstellen und mit [c]@Autowired[/c] dann in jeder beliebigen, in Spring ebenfalls erfassten Klasse anhängen. Aber wenn du dich für so was interessierst, dann schau einfach mal online nach Spring-Beispielen
Ich sag's auch nochmal: Schau dir unbedingt Dependency Injection an! Dann wirst du nie mehr auf die Idee kommen, deine Projekte mit global-statischen Antipattern zu vermurksen.
Ein kurzes, einfaches Beispiel für DI mit dem Springframework findet man hier: http://www.java-forum.org/blogs/tfa/27-how-dependency-injection-spring.html
Vielen Dank.
Wird DI von Eclipse unterstützt? Im Internet findet sich auch die kleine Anmerkung "DI wird nicht von IDEs unterstützt weshalb der Code unüberischtlicher wird.". Und das mehr als einmal.
PS: Ich würd gerne mal mit einem Entwickler von Java reden was die sich dabei gedacht haben static einzubaun wenn es anscheinend nicht der "Sinn" von Java ist
PPS: Ich muss aufpassen. Jetzt hab ich doch glatt den Thread hier erobert
Was meinst du mit der Unterstützung von DI in IDEs?
DI hat den Vorteil dass ALLE Abhängigkeiten im Konstruktor direkt ersichtlich sind und nicht irgendwo in Zeile 563 nen statischer Singleton Aufruf versteckt ist.
Ich würd gerne mal mit einem Entwickler von Java reden was die sich dabei gedacht haben static einzubaun wenn es anscheinend nicht der "Sinn" von Java ist
PS: Ich würd gerne mal mit einem Entwickler von Java reden was die sich dabei gedacht haben static einzubaun wenn es anscheinend nicht der "Sinn" von Java ist
STATIC ist ein keyword um z.b. der VM zu ermöglichen von außen in dein programm einzusteigen ... denn es hat ja mit sicherheit kein objekt deiner klasse ... *was vorraussetzen würde das jede klasse IMMER einen public konstruktor ohne parameter bräucht* ...
außerdem ist es ein keyword um eine referenz über alle instanzen auf das selbe objekt zeigen zu lassen ...
keiner hat gesagt das STATIC nicht im sinne von java wäre ... wir meinten das lediglich genau auf das von dir gebrachte beispiel bezogen ... weil da macht sich global-static echt nicht gut ...