Java: Immer noch keine echten Templates?
-
puh schon wieder ein beitrag:
da bin ich gerade mit dem anderen fertigDarum geht es doch gerade. Ich will eben nicht selber das machen (und uU es vergessen). Das ist doch das Argument warum ich den GC verwenden soll GC Verfechter sagen: nutze den GC, denn dann kannst du das Freigeben des Speichers nicht vergessen. Nun ist Speicher aber nicht so teuer wie ne DB Verbindung.
im endeffekt wirst du es eh im finalizer stehen haben (das close)
bzw im finalizer der connection klasse ist das close auch drinnenHier helfen dir verschiedene GC algorithmen. du kannst auch den GC regelmaessig aufrufen.
normalerweise reicht der normale GC - oder du benutzt sowieso connection pooling - das optimum in dem bereichja aber in C++ musst du auch daran denken das die verbindung am ende des scopes geschlossen wird. ich bevorzuge es uebrigens dezidiert connections zu schliessen. das erhoeht die lesbarkeit und bringt keine nachteile (IMHO)
gomberl
-
@Helium ... komm nicht mit vorurteilen ....
Naja ich kenne RAII wiklich nicht !RAII ist in Java nicht Möglich, in C++ und D jedoch schon und dort auch sehr beliebt.
es ist garantiert das finalize aufgerufen wird. das wird es immer. allerdings ist nicht garantiert WANN finalize aufgerufen wird, weil es eben vom GC aufgerufen wird bevor das objekt verworfen wird.
Ja und es läuft in 'nem ganz anderen Thread, weshalb man auchnoch auf Synchoronisierung achten muss.
und diese moeglichkeit hast du
den wenn du .close sagst dann ist die db connection geclosed (das heisst belegt keine resource des servers mehr) und kann vom GC bereinigt werdenNein hast du nicht. Du kannst es vergessen bzw. in einer komplexen Situation eine Möglichkeit übersehen. In C++ unmöglich.
-
Ja und es läuft in 'nem ganz anderen Thread, weshalb man auchnoch auf Synchoronisierung achten muss.
Nein synchronisierung ist kein thema bei der GC. Das ding ist kein simpler GC wie er damals in COM (reference counting) verwendet wurde.
ich empfehle hierfeur java.sun.com und auch www.javaworld.comZitat:
und diese moeglichkeit hast du
den wenn du .close sagst dann ist die db connection geclosed (das heisst belegt keine resource des servers mehr) und kann vom GC bereinigt werdenUnmoeglich??
Ich kann auch in C++ vergessen ein free auf ein objekt zu machen.
Kommt nur darauf an ob ich objekte am heap oder stack anlege.
Das Argument kommt bei mir nicht durch. Ich habe schon selbst genug memory leaks in C++ programmiertgomberl
-
Helium schrieb:
und diese moeglichkeit hast du
den wenn du .close sagst dann ist die db connection geclosed (das heisst belegt keine resource des servers mehr) und kann vom GC bereinigt werdenNein hast du nicht. Du kannst es vergessen bzw. in einer komplexen Situation eine Möglichkeit übersehen. In C++ unmöglich.
Ok. In C++ kanst du dafür "delete" vergessen. Der Vorteil an Java ist, dass solche Fehler i.d.R. nicht gleich zu einer Katastrophe führen. Für soetwas gibt es die finalizer. Die sind in so einem Zusammenhang als "Sicherungsmethode" gedacht. Wenn der Programmierer den oben beschriebenen Fehler macht, dann kommt trotzdem i.d.R. nach einiger Zeit der GC, der den finalizer aufruft, in dem dann die entsprechende Abschlussmethode nochmal aufgerufen wird.
(...wie gesagt, das ist nur eine "Sicherung" und soll hier keine Aufforderung sein, die Abschlussmethoden nicht zu nutzen.)
-
ich meinte auch delete
in welcher sprache war es denn "free" .. hmmm
na egal
-
Der GC läuft och in einem eigenen Thread und führt die Finalisierung in seinem Thread aus, oder sehe ich das falsch?
Kommt nur darauf an ob ich objekte am heap oder stack anlege.
Das Argument kommt bei mir nicht durch. Ich habe schon selbst genug memory leaks in C++ programmiertWenn du etwas auf dem Heap anlegst lässt du es einfach von etwas auf dem Stack liegenden verwalten. (Smart-Pointer, ...). Wenn du das nicht tust bist du es selbst schuld.
Wir reden gerade nicht nur über Speicher (wofür ein GC natürlich ganz große Klasse ist!), sondern eben über Dinge, wie Datenbakverbindungen.Niemand sagt, das du nicht trotzdem eine close-Methode implementieren darfst, um vorzeitig zu schließen. Aber C++ sorgt eben dafür, dass spätestens, wenn der Scope verlassen wird das Ding zu ist (auch im Fall eine Exception). In Java muss ich explizit finally-Bereiche schreiben. Das ist doch einfach nur lästig.
-
Zeus schrieb:
Viel schlimmer was mich an Java nervt ist [...] die Standardmässige public virtual deklarierung von Members - ja ich weiss, dass es so gesagt nicht richtig ist
Du sagst es ja selbst. Das, was du da sagst, ist nicht richtig. Wie kann es dich dann an Java stören. Standardmäßig ist in Java nichts public, sondern alles packageprivate. Der Sichtbarkeitsbereich ist auf das Paket eingeschränkt, in dem sich die Klasse befindet.
Das mit "virtual vs. final" ist wohl Geschmackssache. Ob man jetzt markiert, dass etwas überschrieben werden kann oder ob etwas nicht überschrieben werden kann ist IMHO egal. Man muss sich in jedem Fall Gedanken darüber machen, ob man das Überschreiben zuläßt oder nicht.
-
Shade Of Mine schrieb:
Socket sock=null; try { sock=new Socket(); } catch(...) { ... } finally { try { if(foo) foo.close(); } catch(HabIchVergessenException) { } }
Bei sowas frage ich mich: warum keine Destruktoren? Und warum wirft der 'Dtor'? Ich kann meistens dann sowieso nix machen. Höchstens den Fehler loggen...
Mal gucken, in welchem Fall beim Schließen des Sockets eine Exception geworfen wird...
Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.
Wie sollte das denn sonst gelöst werden? Einfach den Socket schließen und die Threads, um die es da geht, auf etwas "ungültiges" zugreifen lassen? Das kann ja wohl nicht die Lösung sein. So eine Exception muss man einfach schmeißen und behandeln.
-
Wobei mir das final schon lieber ist. Weil final kann ich vergessen, wenn ich virtual vergesse, hab ich evtl. nen hard-to-find-bug. Außerdem verbietet ja niemand der VM, für Aufrufe an nicht-redefinierte Methoden, ne feste Aufrufaddresse zu verwenden.
Was mich an Java stört, ist das gammelige protected, was halt überhaupt nichts protected, sondern noch öffentlicher wie das package-private ist. Das find ich mal wirklich schlecht.
-
Wenn du etwas auf dem Heap anlegst lässt du es einfach von etwas auf dem Stack liegenden verwalten. (Smart-Pointer, ...). Wenn du das nicht tust bist du es selbst schuld.
Wir reden gerade nicht nur über Speicher (wofür ein GC natürlich ganz große Klasse ist!), sondern eben über Dinge, wie Datenbakverbindungen.Alles liegt im speicher.
Datenbankverbindungen auch.Mir geht es um das triggering des destructors.
und der ist AFAIK getriggered wenn der scope verlassen wird oder wenn ich ein delete mache.
das heisst mache ich kein delete auf etwas das am heap erzeugt wurde so habe ich ein memory leak und eine nicht schliessende verbindung. punktum. und das ist moeglich in C++, ganz einfach. WIE ich jetzt gegen sowas vorbeugen kann war nicht gegenstand der diskussion.
ich habe auf den satz "In C++ unmöglich" geantwortet, weil er nonsens ist.wobei ich sagen muss das ich schon sehr aus der C++ programmierung heraussen bin.
-
Optimizer schrieb:
Was mich an Java stört, ist das gammelige protected, was halt überhaupt nichts protected, sondern noch öffentlicher wie das package-private ist. Das find ich mal wirklich schlecht.
ja das find ich auch sehr verwirrend - da ham sich die sprachen designer ausgezeichnet
-
Ich glaube die Diskussion über Destruktoren sollten wir bleiben lassen...
@gomberl:
Ich verstehe nur immer noch nicht, warum ein
a.add(b); bzw.
x=Foo.add(a,b);
besser ist als
a+=b; bzw.
x=a+b;Ich weiss bei einem add() genausowenig über die Aktion wie bei einem operator+
-
Das Destruktor-Konzept würde für Java einfach keinen Sinn machen, weil man dann vorschreiben müsste, wann ein Destruktor aufgerufen wird.
Wenn sich ein Programmierer dann acuh sowas verlässt, kümmert er sich indirekt schon wieder um die Speicherverwaltung und die soll ja in Java automatisch stattfinden.
Man soll sich um nichts kümmern müssen, das ist einfach eine andere Philosophie. Man überlässt die Speicherverwaltung komplett der VM, die das sowieso viel besser macht, als man es von Hand coden würde.
Daraus ergeben sich auch ein paar Nachteile, da hat Shade nicht ganz unrecht. Aber in C++ ist es IMO trotzdem leichter, ganz allgemein ein paar Sachen zu vergessen, in Java muss man sich nicht um so viel kümmern.Operatoren: Ich vermisse Operator-Überladung in Java auch. Es ist theoretisch nicht notwändig und auch gerade aufgrund der Referenz-Semantik ein bisschen problematisch bei == und !=. Da finde ich den Graben zwischen == und equals() schon gut, den sollte man auch nicht ändern können.
Aber ein + und - überladen, wär schon was feines manchmal.
-
gomberl schrieb:
Alles liegt im speicher.
Datenbankverbindungen auch.Aber der Unterschied zwischen Speicher und DB Verbindung ist dir klar?
Das eine ist ne kritische Resource (DB) das andere eine Resource die nahezu unendlich vorhanden ist.Mir geht es um das triggering des destructors.
und der ist AFAIK getriggered wenn der scope verlassen wird oder wenn ich ein delete mache.
das heisst mache ich kein delete auf etwas das am heap erzeugt wurde so habe ich ein memory leak und eine nicht schliessende verbindung. punktum. und das ist moeglich in C++, ganz einfach. WIE ich jetzt gegen sowas vorbeugen kann war nicht gegenstand der diskussion.Doch.
C++ bringt nunmal wenig in die Sprache integrierte 'Features' mit.
Nur aus diesen Features lassen sich eben Sachen basteln: wie zB das RAII Idiom.
Und deshalb gibt es in einem guten C++ Programm keine Resource Leaks - weil eben alles über Destruktoren zerstört wird (auch dynamisch allokierter Speicher).Das man auch die Möglichkeit hat, dieses Feature nicht zu nutzen ist doch kein Nachteil der Sprache.
-
shade: in dem fall weisst du genausoviel da hast du recht
die (vom mir bereits erfahrene problematik) liegt darin das das einlesen laenger dauert - bzw man fehler leichter uebersieht.IMHO. IME (in my experience)ich finde einfach das methodenaufrufe besser lesbar sind und man sich auch mehr darunter vorstellen kann (speziell wenn die namen gut gewaehlt sind)
bei add und + ist kein unterschied (das sagt beides nicht viel wenn die objekte nicht gerade irgendwelche mathematischen oder graphischen dinge sind)
ich persoenlich habe das operator ueberladen sehr gerne genutzt bis zu dieser erfahrung.
seither benutze ich es nicht mehr. methodenaufrufe sind genausogutmeine meinung
gomberl
-
a = (b + c) * (d + e);
a.assign(b.add(c).mul(d.add(e));
LOL
-
Aber der Unterschied zwischen Speicher und DB Verbindung ist dir klar?
Das eine ist ne kritische Resource (DB) das andere eine Resource die nahezu unendlich vorhanden ist.das ist mir schon klar.
Ich weiss auch auf was du hinaus willst, aber das aendert meine ansicht nicht das ein .close() benutzt werden sollte.
eine kritische resource gehoert dezidiert geoeffnet und dezidiert geschlossen. IMHO.C++ bringt nunmal wenig in die Sprache integrierte 'Features' mit.
Nur aus diesen Features lassen sich eben Sachen basteln: wie zB das RAII Idiom.
Und deshalb gibt es in einem guten C++ Programm keine Resource Leaks - weil eben alles über Destruktoren zerstört wird (auch dynamisch allokierter Speicher).Das man auch die Möglichkeit hat, dieses Feature nicht zu nutzen ist doch kein Nachteil der Sprache.
ueber RAII hab ich 2 mal gelesen in meinem leben, dementsprechend kann ich nix dazu sagen.
ich will hier auch C++ nicht schlecht machen.
Ich weiss auch das es in einem guten C++ prorgramm keine resource leaks gibt, habe auch schon so etwas geschrieben, man glaubt es kaum.Frage: wieviele "gute" C++ programme kennst du. Ich sage gerade 20 prozent sind gut geschrieben, weil eben sehr viel zeitdruck auf den personen lastet und man nicht alles machen kann. man hat auch organisatorische aufgaben und dann kommen noch altlasten hinzu.
Fuer alles weiter koennen wir einen thread ueber software quality management aufmachen. Auch verweise ich auf den Chaos Report. Jedes jahre wieder eine freude zu sehen wieviele IT projekte in die hose gehen.Das man auch die Möglichkeit hat, dieses Feature nicht zu nutzen ist doch kein Nachteil der Sprache.
das hab ich auch nie behauptet. ich habe nur behauptet das "C++ nicht die eierlegende wollmilchsau ist" -> "In C++ unmoeglich"
In C++ ist viel mehr moeglich. auf der positiven wie auch auf der negativen seite. Und das ist auch gut so.
-
@me_:
und jetzt erklaerst du mir was
a = (b + c) * (d + e);
bedeutet wenn
a .. Klasse_Flugzeug
b .. Klasse_Auto
c .. Klasse_Sprit
d .. Klasse_WasWeissIchNoch
e .. Klasse_KeineAhnungist
ach ja - dasselbe problem hast du in java auch
aber dort wuerdest du wohl fuer b + c sagen b.betanke(c)
-
gomberl schrieb:
@me_:
und jetzt erklaerst du mir was
a = (b + c) * (d + e);
bedeutet wenn
a .. Klasse_Flugzeug
b .. Klasse_Auto
c .. Klasse_Sprit
d .. Klasse_WasWeissIchNoch
e .. Klasse_KeineAhnungist
ach ja - dasselbe problem hast du in java auch
aber dort wuerdest du wohl fuer b + c sagen b.betanke(c)Wenn du Operatoren dort einsetzt wo sie niemand verwenden würde ist das deine Sache,
Operatorenüberladung ist dazu da dir das Leben leichter zu machen nicht schwerer.
Niemand würd die aktion auftanken über einen Operator lösen, sondern über eine
Methode.
-
aber dort wuerdest du wohl fuer b + c sagen b.betanke(c)
Nie und nimmer! Man kann antürlich auch schwachsinnige Seiteneffekte implementieren aber wenn man von einem halbwegs normalen Design ausgeht, dann wird 'b + c' 'b' nicht verändern.
Das man auch die Möglichkeit hat, dieses Feature nicht zu nutzen ist doch kein Nachteil der Sprache.
das hab ich auch nie behauptet. ich habe nur behauptet das "C++ nicht die eierlegende wollmilchsau ist" -> "In C++ unmoeglich"
Du hast den Zusammenhang nicht ganz verstanden. Wenn du die entsprechenden Features nicht nutzt ist es natürlich möglich. Solltest du aber die dir angebotenen Features nutzen, so ist es unmöglich!