RAII und Java

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Stephan Theisgen
Beiträge: 94
Registriert: 29.07.2003, 11:13

Re: RAII und Java

Beitrag von Stephan Theisgen »

Disclaimer: Achtung das ist ein sehr langer Text geworden, also es sollte sich niemand gezwungen fühlen es zu lesen. Es beinhaltet auch keine guten Tipps oder so, sondern lediglich meine Ansichten und bescheidenen Erkenntnisse zu diesem Thema... Aber meine Lernkurve steigt gerade enorm. Dank dieser hervorragenden Diskussionen, die hier in letzter Zeit immer wieder laufen...

Hi!

So, jetzt muss ich doch auch mal meinen Senf dazu geben...

Zunächst wollte ich schreiben, dass ich an C++ den Scope und die Lebenszeit von Objekten sehr zu schätzen weiß, auch die Kontrolle darüber, aber ich immer die Möglichkeit vermisst habe, Objekte zurück zu geben und so die Lebenszeit in den übergeordneten Scope zu verlängern. Ein Beispiel, was ich damit meine:

Code: Alles auswählen

object& someFunction() {
   object o();
   return o;  //die Lebenszeit von o sollte nicht mit der Funktion enden, sondern an den übergeordneten Scope übergehen
}

void mainFunction() {
   object& o = someFunction();
} //object o sollte erst hier zerstört werden
Allerdings muss ich sagen, durch das Mitlesen hier, habe ich mich endlich mal mit dem neuen Standard beschäftigt dabei zum ersten mal rvalues und move-Semantik begriffen und war begeistert, dass dieses Problem der Übergabe von Besitzrechten nun einfach und performant gelöst wurde. Ich bin begeistert!!! (By the way: Wie bekomme ich an dieses neue C++? Meine aktuelles VS kann das nämlich nicht?) Da kann man mal sehen, was einem solch ein Thread bringt. Und ich glaube auch, dass noch mehr Leute wie ich hier einfach mitlesen und dabei viel lernen.

Ein anderes Problem ist ein reines Software-Design-Problem. Es gibt Objekte die sind nur temporär und sollen nur kurz leben, dafür ist der Stack und ein Scope hervorragend geeignet. Und ich finde, dass ist in C++ mit Destruktoren etc. hervorragend geregelt. Richtig eingesetzt sorgt es für ein hervorragendes aktuelles aufräumen dieser temporären Objekte ohne viel Aufhebens.
Dann aber gibt es Objekte die erzeugt werden und länger leben sollen, vielleicht viel rum gereicht werden. Solange die Besitzverhältnis leicht zu überblicken sind, und z.B. nur ein anderes Objekt für die Verwaltung zuständig ist, ist das Ganze noch recht einfach zu überblicken, das Besitzer-Objekt verwaltet und löscht auch, denn es weiß genau wann die erzeugten Objekte nicht mehr benötigt werden. Wenn die Verhältnisse komplizierter sind, dann gehe ich meist dazu über die Lebenszeit dem erzeugten Objekt selbst zu überlassen (z.B. mittels Referenzzählung) das ist aber nicht so einfach, wie es sich anhört. Zwar weiß in einer solch komplexen Situation dann das erzeugte Objekt noch am besten Bescheid, aber auch sein Wissen ist begrenzt. Es kennt ja nur sich selbst. Zyklische Abhängigkeiten führen dann zu Geisterobjekten. Diese Probleme sind nicht so einfach zu lösen und C++ bietet dort keine vorgefertigte einfache Hilfe wie im ersten Fall der temporären Objekte.
Allerdings bin ich inzwischen auch soweit, dass ich einen GC nicht mehr als die Lösung, sondern nur als eine Verschleierung des Problems ansehe. Trotzdem bereitet mir diese Situationen häufig Kopfzerbrechen und viel eigene Arbeit... Wenn hier also jemand dafür ein Patentrezept kennt?

Und jetzt muss ich am Ende doch noch eine Lanze für Java brechen.
Ich habe lange in C++ programmiert und es war sehr schwierig ein funktionierendes Programm hinzubekommen, das etwas komplexer ist. Da man sich um so viel selber kümmern muss und sobald ein Design nicht perfekt ist, muss man alles wieder von vorne Anfangen, neu designen etc. Hinzu kommt, dass es ein Alptraum ist, ein GUI in C++ zu schreiben und zu verwalten. Das liegt auch einfach daran, dass ein kompliziertes GUI für ein aufwendiges Programm eine sehr komplexe Sache ist. Das sieht man schon daran, dass auch "Profi"-Bibliotheken wie wxWidgets oder Qt sehr komplex sind und sich bei größeren Programmen einfach mal ohne ersichtlichen Grund verabschieden und das ganze Programm mitreißen. Meine C++ Programme sind nie am eigentlichen Arbeitsalgorithmus oder der Datenverwaltung gescheitert, immer nur an der mit C++ kaum zu beherrschenden Komplexität der GUI. Aber gerade für mich, der Programme auch häufig nur als Hilfsmittel und nicht nur als Selbstzweck entwickelt, sollte die GUI-Entwicklung einfach und schnell am besten durch Zusammenklicken von statten gehen.

Ein Beispiel: auf der Arbeit habe ich eine bestimmte Aufgabe zu erfüllen. Ich denke mir: statt von Hand ginge das mit einem Programm aber deutlich schneller. Vorausgesetzt ich schaffe die Programmierung in ca. 1 Woche. In C++ dauert alleine die GUI 1 Jahr, läuft dann immer noch nicht stabil und ich verliere irgendwann, wenn ich auf einen Button klicke alle meine ach so wichtigen Daten, weil das Programm einfach abbricht! In Java schaffe ich das locker in 3 Tagen und wenn dann noch Fehler drin sind, dann sieht höchstens plötzlich der Button komisch aus, aber die Daten habe ich eigentlich noch nie verloren. Mit Java habe ich es geschafft meine Programmierkenntnisse das erste Mal sinnvoll und nicht nur zum Selbstzweck einzusetzen. Somit kommt es, dass ich solche Sachen fast nur noch mit Java programmiere und kaum noch mit C++. In meiner Freizeit aber, benutze ich C++, da ich hier viel Zeit habe die Programme fertig zu stellen und ich sozusagen perfekten schönen Code schreiben möchte.

Viele Grüße und vielen Dank fürs Lesen ;-)
Stephan

P.S.: Interessant fand ich auch immer den unterschiedlichen Workflow: in C++ fand ich es immer einfach den eigentlichen Algorithmus richtig, sauber und performant zu schreiben. Aber das ganze Drumherum war ein Alptraum. In Java war es immer genau umgekehrt. Das Drumherum war schnell gemacht und sah ansprechend aus. Den eigentlichen Algorithmus aber performant und richtig hinzubekommen war meist sehr schwierig (Hacks waren häufig nötig).
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Stephan Theisgen hat geschrieben:(By the way: Wie bekomme ich an dieses neue C++? Meine aktuelles VS kann das nämlich nicht?)
Wenn du Visual Studio 2010 hast, dann kann es das. Lambdas, rvalue Referenzen und Teile der neuen Standardbibliothek sind da unter anderem schon drin. Aber leider ist der C++11 Support in VS atm noch mager. Das wird sich aber hoffentlich in näherer Zukunft ändern...
Benutzeravatar
spobat
Beiträge: 86
Registriert: 13.09.2010, 00:20
Kontaktdaten:

Re: RAII und Java

Beitrag von spobat »

Gibt es eigentlich handfeste Beweise oder Benchmarks / Analysen, die diese Vermutung belegen?
Im grunde werden die Dateien ja auch ueber c++ code geoeffnet und geschlossen.

Ich sehe das nicht so tragisch.
Die Behauptung ist ja, es gibt ein Leak, falls ein Reader / Writer /Stream im Konstruktor eine Exception wirft.

Wenn ich mir die Java Klasse mal genau ansehe, wirft keine der genannten Klassen per definition eine Exception .
(Ausnahme, die FileNotFoundException, welche aber, tritt sie ein, nicht einmal zu einem belegten FileHandle fuehren wuerde).

Wo liegt also das Problem?
In der schlechten Programmierung, wenn man versucht, sich eigene Reader/Writer/Stream Klassen zu bauen.
Ganz ehrlich, sowas habe ich bisher noch nie gebraucht, und mir faellt spontan auch kein Grund ein, warum man von z.b. FileReader ableiten sollte? (Ich bitte um Beispiele :))
Die Anzahl der Programme, in denen solcher Code vorliegt, geht sehr klar gegen null.

Wenn ich also schlecht programmiere, entstehen Leaks. Das trifft fuer z.B. fehlende "delete" calls in c++ aber genau so zu.
Man muss in Java beim ableiten genannter Klassen aufpassen, dass man im Konstruktor keine Exceptions werfen darf - sollte dieses Theorie ueberhaupt belegt werden -
wie man auch nicht vergessen darf, einem "new" ein "delete" nachzuschieben.

Beides ist natuerlich irgendwo schlecht, da man immer etwas im Hinterkopf behalten sollte, was man eigentlich nicht muessen sollte.

Gluecklicherweise hilft uns auch das OS etwas unter die Arme. By default laeuft jedes Java Programm in einer eigenen VM. Wird das Programm beendet, werden immer noch belegte filehandles vom system erkannt
und "bereinigt". Somit ist nach dem "run" des Programms wieder alles im Reinen. Sowas koennte hoechstens bei Serveranwendungen / Java EE / interessant werden; Beachte andren Punkte.
Wenn ihr mich fragt, gibt es in der Informatik wirklich wichtigeres zu tun, vorallem, da es ja kein Leak gigantischen ausmaßes ist, das spontan mal 800mb ram belegt.
Ich hatte auf keiner meiner Maschinen bisher eine "Keine freien filehandles mehr!" Fehlermeldung.

Vielleicht ist auch dieser Link hier angebracht: http://www.oracle.com/technetwork/artic ... 01775.html (Suche nach "leak")
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

dst hat geschrieben:Gibt es eigentlich handfeste Beweise oder Benchmarks / Analysen, die diese Vermutung belegen?
Im grunde werden die Dateien ja auch ueber c++ code geoeffnet und geschlossen.
Was genau meinst du damit? Was für Vermutungen?
dst hat geschrieben:Die Behauptung ist ja, es gibt ein Leak, falls ein Reader / Writer /Stream im Konstruktor eine Exception wirft.
Was das Beispiel betrifft, ist das keine Behauptung sondern Fakt.
dst hat geschrieben:Wenn ich mir die Java Klasse mal genau ansehe, wirft keine der genannten Klassen per definition eine Exception.
(Ausnahme, die FileNotFoundException, welche aber, tritt sie ein, nicht einmal zu einem belegten FileHandle fuehren wuerde).
Das ist nicht der Punkt. Ersetz die Klassen eben durch irgendwelche anderen Klassen. Worum es geht ist: Du hast hier ein Beispiel für Code der völlig harmlos und sicher aussieht, aber in Wirklichkeit potentiell leaked. Man muss verdammt aufpassen um in Java nicht zu leaken, da die Sprache nicht nur keine vernünftige Lösung für all die aufgezeigten Probleme bietet, sondern schon per Design eine solche mit aller Kraft verhindert.
dst hat geschrieben:Die Anzahl der Programme, in denen solcher Code vorliegt, geht sehr klar gegen null.
Klar, wenn du das sagst, dann muss es natürlich so sein...
dst hat geschrieben:Wenn ich also schlecht programmiere, entstehen Leaks. Das trifft fuer z.B. fehlende "delete" calls in c++ aber genau so zu.
Man muss in Java beim ableiten genannter Klassen aufpassen, dass man im Konstruktor keine Exceptions werfen darf - sollte dieses Theorie ueberhaupt belegt werden -
wie man auch nicht vergessen darf, einem "new" ein "delete" nachzuschieben.
Das ist nicht der Punkt. Der Punkt ist, dass es in Java sehr schwer ist, gut zu programmieren, während es z.B. in C++ für all die genannten Probleme sehr simple und elegante Lösungen gibt.
dst hat geschrieben:Gluecklicherweise hilft uns auch das OS etwas unter die Arme. By default laeuft jedes Java Programm in einer eigenen VM. Wird das Programm beendet, werden immer noch belegte filehandles vom system erkannt
und "bereinigt". Somit ist nach dem "run" des Programms wieder alles im Reinen. Sowas koennte hoechstens bei Serveranwendungen / Java EE / interessant werden; Beachte andren Punkte.
Wenn ihr mich fragt, gibt es in der Informatik wirklich wichtigeres zu tun, vorallem, da es ja kein Leak gigantischen ausmaßes ist, das spontan mal 800mb ram belegt.
Ich hatte auf keiner meiner Maschinen bisher eine "Keine freien filehandles mehr!" Fehlermeldung.

Vielleicht ist auch dieser Link hier angebracht: http://www.oracle.com/technetwork/artic ... 01775.html (Suche nach "leak")
Ja, das OS räumt natürlich auf. Das ändert aber nix dran dass das Programm leaked. Und es geht hier eben genau nicht um Speicher. Speicher ist praktisch die einzige Ressource bei der man in Java nicht leaked, da der Garbage Collector sich ja drum kümmert. Jede andere Art von Ressource ist dafür aber unglaublich anstregend zu managen und man kann an allen Ecken und Enden was falsch machen. Das Beispiel mit dem BufferedReader sollte ja demonstrieren, dass auch try-with-resources wieder keine zufriedenstellende Lösung ist. In C++ gibt es mit RAII dagegen eine einfache Lösung bei der der Compiler sich automatisch um alles kümmert ohne dass man dort wo die Ressource verwendet wird auch nur eine einzelne Zeile Code dafür schreiben muss. Und zwar für jede Art von Ressource, nicht nur für Speicher. Auch sind die Probleme mit Leaks weitaus komplexer als dass einem einfach nur mal die freien Filehandles ausgehen. Nehmen wir z.B. gleich bei Dateien. Wenn du eine Datei öffnest und nichtmehr korrekt schließt, dann bedeutet das nicht nur, dass ein Filehandle verloren ist. Es bedeutet vor allem, dass die Datei (je nachdem wie sie geöffnet wurde) von niemand anderem verwendet werden kann bis das Programm beendet...

Der verlinkte Artikel ist lächerlich. Er zeigt schon selbst auf, dass try-with-resources am Ende eben doch nur syntactic sugar ist. Und dass try-with-resources eben genau nicht die Antwort, sondern wieder nur eine weitere spezielle Lösung für einen winzigen Spezialfall ist, wurde hier ja schon ausreichend diskutiert.
Zuletzt geändert von dot am 01.06.2012, 09:37, insgesamt 1-mal geändert.
Benutzeravatar
spobat
Beiträge: 86
Registriert: 13.09.2010, 00:20
Kontaktdaten:

Re: RAII und Java

Beitrag von spobat »

dot hat geschrieben:Was genau meinst du damit? Was für Vermutungen?
Siehe folgende.
dst hat geschrieben:Was das Beispiel betrifft, ist das keine Behauptung sondern Fakt.
Kannst du das Belegen?
dst hat geschrieben:Das ist nicht der Punkt. Ersetz die Klassen eben durch irgendwelche anderen Klassen. Worum es geht ist: Du hast hier ein Beispiel für Code der völlig harmlos und sicher aussieht, aber in Wirklichkeit potentiell leaked. Man muss verdammt aufpassen um in Java nicht zu leaken, da die Sprache nicht nur keine vernünftige Lösung für all die aufgezeigten Probleme bietet, sondern schon per Design eine solche mit aller Kraft verhindert.
Das klingt fuer mich eher nach "Fanboy". Das ist eben schon ein Punkt, da das die Dateimanagement-Klassen sind, um die es hier ja geht.
"Man muss verdammt aufpassen um in Java nicht zu leaken": Beispiele, neben dem Dateimanagement?
dot hat geschrieben:Klar, wenn du das sagst, dann muss es natürlich so sein...
dst hat geschrieben:mir faellt [...] kein Grund ein, warum man von z.b. FileReader ableiten sollte? (Ich bitte um Beispiele )
Wenn du hier zahlreiche, sinnvolle Beispiele nennen kannst, nehme ich meine Behauptung, das sowas in ueber 99.999999% der Applikationen nicht vorhanden ist, zurueck.

dot hat geschrieben:Er zeigt schon selbst auf, dass try-with-resources am Ende eben doch nur syntactic sugar ist. Und dass try-with-resources eben genau nicht die Antwort, sondern wieder nur eine weitere spezielle Lösung für einen winzigen Spezialfall ist, wurde hier ja schon ausreichend Diskutiert.
Der Artikel beschreibt keine neuen Sprachfeatures, sondern try-with-resources ist tatsaechlich nur syntactic sugar. Interessant ist auch, dass Konstruktoren hier nicht angesprochen werden,
sondern nur die Kapselung und der close() Mechanismus. Interessant ist aber auch, dass in dem Artikel garantiert wird, dass es zu keinem leak kommen wird.
Als laecherlich wuerde ich ihn nicht bezeichnen, da er von Oracle kommt, worauf man normal einiges halten kann.
Better Resource Management with Java SE 7: Beyond Syntactic Sugar hat geschrieben:The benefits of the try-with-resources statement in Java SE 7 are self-explanatory for such an example: You have less code to write, the code is easier to read, and, last but not least, the code does not leak resources!
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Lies den Thread doch bitte einfach mal aufmerksam durch, dann werden alle deine Fragen beantwortet ;)
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: RAII und Java

Beitrag von Psycho »

Kann einer von euch seinen Nick ändern?
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

hehe nur wenn dst das möchte :)

ich stimme, wie sich ja sicher auch aus meinen vorherigen posts entnehmen lässt, dst zu. wir haben ja im verlauf der diskussion schon "herausgefunden", dass gc und raii nicht zusammen funktionieren können. da hab ich lieber einen gc. der erspart mir viel mehr fehler als das permanente bedenken von raii... das gilt besonders für situationen in denen man sich nicht aussuchen kann mit wem man an einem projekt arbeitet und nicht die zeit für peer reviews da ist.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Chromanoid hat geschrieben:ich stimme, wie sich ja sicher auch aus meinen vorherigen posts entnehmen lässt, dst zu. wir haben ja im verlauf der diskussion schon "herausgefunden", dass gc und raii nicht zusammen funktionieren können.
Nanu? Wo haben wir denn das rausgefunden? Sprachen wie z.B. D sind doch der lebende Beweis dafür, dass das möglich ist. Nur in Java ist es eben unmöglich. Andere Sprachen bieten sehr wohl die entsprechenden Möglichkeiten. Wobei es natürlich fraglich ist, inwiefern ein Garbage Collector überhaut Sinn macht, wenn man eh RAII hat...
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

klar geht beides in einer Sprache, aber nicht so wie man es in C++ gewöhnt ist. oder wie willst du RAII benutzen, wenn du nicht weißt wann der GC deine Objekte abräumt? Sicher kann man wie in C++ den Scope nehmen um das Objekt zu destruieren, aber ist dass dann wirklich RAII, wenn das nur die Code-Stücke betrifft, die nicht vom GC gemanaged werden? RAII wird doch erst nützlich, wenn die Nutzung von Ressourcen an die Lebenszeit eines Objektes gebunden ist. Ansonsten ist das Nutzen einer Ressource doch nur ein bisschen einfacher als bei Java, weil man nicht ans close() denken muss.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Das ist natürlich richtig, darum ist es natürlich fraglich, wie sinnvoll es ist überhaupt einen GC zu haben ;)
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

naja im grunde führt es nur zu einer entscheidung ob man nun raii oder gc exzessiv nutzen will. ich entscheide mich da wie gesagt für den gc...
Benutzeravatar
spobat
Beiträge: 86
Registriert: 13.09.2010, 00:20
Kontaktdaten:

Re: RAII und Java

Beitrag von spobat »

Leider war ich nicht von anfang dabei, und konnte direkt meine Meine aussern, das bereue ich nun etwas.
Besonders zu CodingCat's beitraegen laesst sich viel sagen. Deshalb hole ich jetzt etwas nach :)

Zum Beispiel das (3. Seite in diesem Thread):
CodingCat hat geschrieben:Man beachte, dass das nicht 100% ausnahmesicher ist, sollte ScopeGuard bei seiner Erzeugung eine OutOfMemoryException hervorrufen. Darunter leiden aber wohl sehr sehr viele try-with-resources-Beispiele. Wer braucht schon lückenlos?
In Java gibt es keine OutOfMemoryException. Nennt sich OutOfMemoryError.
Da hast du natuerlich erstmal recht, sowas kann IMMER fliegen, total unvorhergesehen.
Witzig ist aber auch, dass dann das Programm sofort crasht und sowieso alle Resourcen freigegeben werden. *g*

Btw.: OutOfMemoryException ist .Net
Ich weiss es zwar nicht, aber ich wette auch dort crasht dann das Programm

Ich glaube, es geht hier nur noch um das Ableiten von FileManagement Klassen und dessen "exceptionwerfenden" Konstruktor, liege ich da richtig?

Was mir besonders in dem Thread aufgefallen ist, ist dass CodingCat und dot unglaublich
viele Behauptungen aufstellen, aber ohne Belege oder Beispiele. Das finde ich ehrlich
gesagt sehr schade. Man moechte das selbst ja auch gerne nachpruefen.
(Behauptung, Begruendung, Beispiel und so :) )


Chromanoid hat geschrieben:
NytroX hat geschrieben:Aber speziell das try-with-resources hat noch ein ganz anderes Problem: man muss genau wissen was man tut. Z.B:

Code: Alles auswählen

try (BufferedReader br = new MyBufferedReader(  
            new MyFileReader("C:/temp/file.txt"))) {  
            System.out.println(br.readLine());  
        } 
kann ein Resource-Leak sein. Und meiner Meinung nach ist das alles andere als offensichtlich.
Stimmt natürlich, try-with-resources lädt da zu solchen gefährlichen Spielchen ein. Nur fürs Protokoll, "richtig" wäre:

Code: Alles auswählen

try (MyFileReader mfr=new MyFileReader("C:/temp/file.txt"); BufferedReader br = new MyBufferedReader(mfr)) {  
    System.out.println(br.readLine());  
} 
Nein, die beiden sind identisch. Ein close() call auf MyBufferedReader wuerde auch das close() des MyFileReader callen.
CodingCat hat geschrieben:
NytroX hat geschrieben:Aber speziell das try-with-resources hat noch ein ganz anderes Problem: man muss genau wissen was man tut.

Code: Alles auswählen

try (BufferedReader br = new MyBufferedReader(  
            new MyFileReader("C:/temp/file.txt"))) {  
            System.out.println(br.readLine());  
        }  
kann ein Resource-Leak sein. Und meiner Meinung nach ist das alles andere als offensichtlich.
Ja, das betrachte ich auch mit großer Sorge, zumal dein Beispiel genau so in dem entsprechenden offiziellen Abschnitt zur Einführung der neuen Sprachfeatures anzutreffen ist.
Wo, Link?


@dot, jetzt zu dir ;)
Ich haette trotzdem gerne folgende Behauptungen bewiesen / beantwortet:
- Eine Exception in einem von einer FileManagement-Klasse (gemeint sind Reader, Writer und Streams) abgeleiteten Klassenkonstruktur fuehr unweigerlich zu einem Filehandle-Leak. Die Sprache darfst du dir aussuchen :)
- Wieso sollte man eine solche Klasse ableiten?
- Wieso sollte eine dieser Klassen eine (nicht fatale) Exception im Konstruktor werfen, nachdem ein valides FileHandle besorgt wurde? (+Beispiel :))
dot hat geschrieben:Man muss verdammt aufpassen um in Java nicht zu leaken
Beispiele, neben dem Dateimanagement?
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

dst hat geschrieben:Was mir besonders in dem Thread aufgefallen ist, ist dass CodingCat und dot unglaublich
viele Behauptungen aufstellen, aber ohne Belege oder Beispiele. Das finde ich ehrlich
gesagt sehr schade. Man moechte das selbst ja auch gerne nachpruefen.
(Behauptung, Begruendung, Beispiel und so )
Sorry, aber das was wir hier gesagt haben war wesentlich fundierter und begründeter als alles, was du bis jetzt hier abgelassen hast. Und solange das so bleibt, bin ich nicht bereit, mit dir überhaupt zu diskutieren. Wir hatten hier gesehen, dass RAII ein sehr mächtiges Werkzeug ist, inhärent sicheren Code zu schreiben, auch unabhängig von der Qualität (oder Exception Specification) einzelner Implementierungen und auch unabhängig von Garbage Collection. Dass Chromanoid das schon wieder vergessen hat, ist traurig, aber kann ich jetzt auch nicht ändern.

Deine seltsamen Anmerkungen zeigen obendrein, dass du nicht mal das Problem erfasst hast.
Zuletzt geändert von CodingCat am 01.06.2012, 10:51, insgesamt 2-mal geändert.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

dst hat geschrieben:
Chromanoid hat geschrieben:
NytroX hat geschrieben:Aber speziell das try-with-resources hat noch ein ganz anderes Problem: man muss genau wissen was man tut. Z.B:

Code: Alles auswählen

try (BufferedReader br = new MyBufferedReader(  
            new MyFileReader("C:/temp/file.txt"))) {  
            System.out.println(br.readLine());  
        } 
kann ein Resource-Leak sein. Und meiner Meinung nach ist das alles andere als offensichtlich.
Stimmt natürlich, try-with-resources lädt da zu solchen gefährlichen Spielchen ein. Nur fürs Protokoll, "richtig" wäre:

Code: Alles auswählen

try (MyFileReader mfr=new MyFileReader("C:/temp/file.txt"); BufferedReader br = new MyBufferedReader(mfr)) {  
    System.out.println(br.readLine());  
} 
Nein, die beiden sind identisch. Ein close() call auf MyBufferedReader wuerde auch das close() des MyFileReader callen.
Wenn man vernünftig entwickelt. Stell dir mal folgendes in MyBufferedReader vor:

Code: Alles auswählen

public MyBufferedReader(Reader in_reader) {
    //...Code der ClassNotFoundException o.Ä. wirft
    reader=in_reader;
}
public void close() throws Exception  {
    reader.close();//reader ist null wenn oben was geworfen wurde.
}
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

@CodingCat: Ich verstehe dann eure Aussagen nicht. Auf der einen Seite soll man RAII unabhängig von GC nutzen können, auf der anderen Seite ist der GC dann eigentlich schädlich bzw. unnütz. Was denn nun?
CodingCat hat geschrieben:
Chromanoid hat geschrieben:Würde man RAII in Java einbauen müsste man ja alles, was mit den jew. Ressourcen zu tun hat, ebenfalls an einen Scope binden, da sonst mögliche Referenzen erst zu einem unbestimmten Zeitpunkt verschwinden würden. Man würde also erst mal auf einen GC verzichten und nur noch mit RAII arbeiten.
Das ist wohl die wichtigste Erkenntnis dieses Threads, genau deshalb braucht eigentlich niemand einen Garbage Collector.
Chromanoid hat geschrieben:klar geht beides in einer Sprache, aber nicht so wie man es in C++ gewöhnt ist. oder wie willst du RAII benutzen, wenn du nicht weißt wann der GC deine Objekte abräumt? Sicher kann man wie in C++ den Scope nehmen um das Objekt zu destruieren, aber ist dass dann wirklich RAII, wenn das nur die Code-Stücke betrifft, die nicht vom GC gemanaged werden? RAII wird doch erst nützlich, wenn die Nutzung von Ressourcen an die Lebenszeit eines Objektes gebunden ist. Ansonsten ist das Nutzen einer Ressource doch nur ein bisschen einfacher als bei Java, weil man nicht ans close() denken muss.
dot hat geschrieben:Das ist natürlich richtig, darum ist es natürlich fraglich, wie sinnvoll es ist überhaupt einen GC zu haben ;)
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Auch mit GC bietet RAII Vorteile, wenngleich der GC dann streng genommen überflüssig wird. Nichts anderes besprechen wir doch hier seit zig Seiten. Siehe RAII-Java-Beispiel etc.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

CodingCat hat geschrieben:Auch mit GC bietet RAII Vorteile, wenngleich der GC dann streng genommen überflüssig wird.
Du sagst hier im Grunde: RAII > GC + RAII > GC Das führt für mich zu der Annahme, dass man entweder RAII nutzt oder GC.
Ich bin der Meinung, dass RAII + GC nicht wirklich die Verschmelzung beider Welten ermöglicht, sondern eben nur eins von beiden Sinn macht. Benutzt man RAII bei GC Objekten ist man genauso wie bei Java darauf angewiesen, dass die gescopte Ressource innerhalb eines oder mehreren Scopes bleibt, die nicht wirklich mit der Lebenszeit des Objektes, das diese Ressource benutzt, zu tun haben.
Zuletzt geändert von Chromanoid am 01.06.2012, 11:10, insgesamt 1-mal geändert.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Chromanoid hat geschrieben:Benutzt man RAII bei GC Objekten ist man genauso wie bei Java darauf angewiesen, dass die gescopte Ressource innerhalb eines oder mehreren Scopes bleibt, die nicht wirklich mit der Lebenszeit des Objektes zu tun haben, das diese Ressource benutzt.
Nicht ganz. Man hat zumindest nicht die Probleme wie bei try-with-resources...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Chromanoid hat geschrieben:
CodingCat hat geschrieben:Auch mit GC bietet RAII Vorteile, wenngleich der GC dann streng genommen überflüssig wird.
Du sagst hier im Grunde: RAII > GC + RAII > GC Das führt für mich zu der Annahme, dass man entweder RAII nutzt oder GC.
Wieso führt dich das zu dieser Annahme? Die einzig logische Schlussfolgerung wäre doch, entweder RAII oder, wenn es nicht anders geht, eben RAII + GC zu nutzen?
Chromanoid hat geschrieben:Ich bin der Meinung, dass RAII + GC nicht wirklich die Verschmelzung beider Welten ermöglicht, sondern eben nur eins von beiden Sinn macht. Benutzt man RAII bei GC Objekten ist man genauso wie bei Java darauf angewiesen, dass die gescopte Ressource innerhalb eines oder mehreren Scopes bleibt, die nicht wirklich mit der Lebenszeit des Objektes zu tun haben, das diese Ressource benutzt.
Nein. Du bekommst es natürlich nicht so lückenlos hin wie in C++. Aber du bekommst es mit wesentlich weniger Lücken hin als im alten Java. Wieso siehst du nur eine Alternative zwischen absolut lückenlos und vollkommen lückenhaft, anstatt je nach Möglichkeiten das beste rauszuholen? Und auch die Überwindung von Geltungsbereichen hatten wir im RAII-Java-Beispiel doch bereits abgehandelt.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

dst hat geschrieben:In Java gibt es keine OutOfMemoryException. Nennt sich OutOfMemoryError.
Da hast du natuerlich erstmal recht, sowas kann IMMER fliegen, total unvorhergesehen.
Witzig ist aber auch, dass dann das Programm sofort crasht und sowieso alle Resourcen freigegeben werden. *g*
Das Programm crashed natürlich nicht sofort wenn du die Exception fängst...
dst hat geschrieben:Ich glaube, es geht hier nur noch um das Ableiten von FileManagement Klassen und dessen "exceptionwerfenden" Konstruktor, liege ich da richtig?
Nein, es geht um die zugrundeliegenden Konzepte und Prinzipien. Aber anstatt das zu realisieren, verbeißt du dich in irgendwelche Beispiele, die lediglich zu Illustrationszwecken dienen sollten...
dst hat geschrieben:
Chromanoid hat geschrieben:
NytroX hat geschrieben:Aber speziell das try-with-resources hat noch ein ganz anderes Problem: man muss genau wissen was man tut. Z.B:

Code: Alles auswählen

try (BufferedReader br = new MyBufferedReader(  
            new MyFileReader("C:/temp/file.txt"))) {  
            System.out.println(br.readLine());  
        } 
kann ein Resource-Leak sein. Und meiner Meinung nach ist das alles andere als offensichtlich.
Stimmt natürlich, try-with-resources lädt da zu solchen gefährlichen Spielchen ein. Nur fürs Protokoll, "richtig" wäre:

Code: Alles auswählen

try (MyFileReader mfr=new MyFileReader("C:/temp/file.txt"); BufferedReader br = new MyBufferedReader(mfr)) {  
    System.out.println(br.readLine());  
} 
Nein, die beiden sind identisch. Ein close() call auf MyBufferedReader wuerde auch das close() des MyFileReader callen.
Selbst wenn man davon ausgeht, dass MyBufferedReader ebenfalls über ein close() verfügt, welches wiederum das entsprechende close() des MyFileReader aufruft, sind die beiden Beispiele nicht identisch. Wenn im ersten Fall der Konstruktor von MyBufferedReader eine Exception wirft, ohne daran zu denken auf seinem Parameter ebenfalls close() aufzurufen, leakest du und kein try-with-resources der Welt wird dir dann helfen. Und genau das ist der Punkt. Du siehst hier Code der völlig sicher aussieht, es aber nicht ist und der Grund wieso das so ist, ist alles andere als offensichtlich. Und auch die Lösung ist nicht einfach, sondern erfordert, dass du an allen möglichen Orten immer und immer wieder den gleichen Code hinschreibst (try/finally mit den entsprechenden close() Aufrufen und rethrow). Und damit nicht genug. Eine weitere Folge dieses Systems mit close() ist, dass jede Klasse, die ein Objekt das ein close() benötigt enthält, selbst wieder ein close braucht...
dst hat geschrieben:@dot, jetzt zu dir ;)
Ich haette trotzdem gerne folgende Behauptungen bewiesen / beantwortet:
Das sind keine Behauptungen, sondern Feststellungen bezüglich des Beispielcodes, die für jeden der Ahnung von Java hat nachvollziehbar sein sollten.
dst hat geschrieben:- Eine Exception in einem von einer FileManagement-Klasse (gemeint sind Reader, Writer und Streams) abgeleiteten Klassenkonstruktur fuehr unweigerlich zu einem Filehandle-Leak. Die Sprache darfst du dir aussuchen :)
Das hab ich nie gesagt. In diesem konkreten Beispiel ist das jedoch so, Erklärung siehe oben. Und die Tatsache dass dir das immer noch nicht aufgefallen ist, zeigt doch sehr schön wie problematisch das ganze ist...
dst hat geschrieben:- Wieso sollte man eine solche Klasse ableiten?
Darum geht es nicht. Du kannst dir von mir aus ein sinnvolleres Beispiel ausdenken, das dann das gleiche Problem hat.
dst hat geschrieben:- Wieso sollte eine dieser Klassen eine (nicht fatale) Exception im Konstruktor werfen, nachdem ein valides FileHandle besorgt wurde? (+Beispiel :))
Darum geht es nicht. Du kannst dir von mir aus ein sinnvolleres Beispiel ausdenken, das dann das gleiche Problem hat.
dst hat geschrieben:
dot hat geschrieben:Man muss verdammt aufpassen um in Java nicht zu leaken
Beispiele, neben dem Dateimanagement?
Hast du eigentlich schonmal irgendwas in Richtung Ressourcenmanagement mit Java gemacht? Die Tatsache dass du hier überhaupt nach Beispielen fragst, lässt eigentlich nur den Schluss zu, dass dem nicht so ist.
Jede Art von Ressource abgesehen von Speicher ist ein Beispiel. Genau darum gehts in dem Thread hier doch!?

Nur um das klarzustellen: Was ich in dieser Diskussion hier so gesagt hab, basiert auf meinen Erfahrungen mit diesen Dingen (Zugegeben, meine Erfahrung hab ich vor allem in C#, aber das ist praktisch das gleiche). Es ist ganz sicher nicht so, dass ich hier einfach so argumentiere ohne zu wissen wieso...
Zuletzt geändert von dot am 01.06.2012, 11:38, insgesamt 4-mal geändert.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

CodingCat hat geschrieben:
Chromanoid hat geschrieben:
CodingCat hat geschrieben:Auch mit GC bietet RAII Vorteile, wenngleich der GC dann streng genommen überflüssig wird.
Du sagst hier im Grunde: RAII > GC + RAII > GC Das führt für mich zu der Annahme, dass man entweder RAII nutzt oder GC.
Wieso führt dich das zu dieser Annahme? Die einzig logische Schlussfolgerung wäre doch, entweder RAII oder, wenn es nicht anders geht, eben RAII + GC zu nutzen?
Wenn man RAII + GC nutzen kann, sollte man mit ziemlich hoher Wahrscheinlichkeit auch nur RAII nutzen können. Wenn man dann aus verschiedenen Gründen doch einen GC einsetzt, wird RAII zu eine Art try-with-resources.
CodingCat hat geschrieben:
Chromanoid hat geschrieben:Ich bin der Meinung, dass RAII + GC nicht wirklich die Verschmelzung beider Welten ermöglicht, sondern eben nur eins von beiden Sinn macht. Benutzt man RAII bei GC Objekten ist man genauso wie bei Java darauf angewiesen, dass die gescopte Ressource innerhalb eines oder mehreren Scopes bleibt, die nicht wirklich mit der Lebenszeit des Objektes zu tun haben, das diese Ressource benutzt.
Nein. Du bekommst es natürlich nicht so lückenlos hin wie in C++. Aber du bekommst es mit wesentlich weniger Lücken hin als im alten Java. Wieso siehst du nur eine Alternative zwischen absolut lückenlos und vollkommen lückenhaft, anstatt je nach Möglichkeiten das beste rauszuholen? Und auch die Überwindung von Geltungsbereichen hatten wir im RAII-Java-Beispiel doch bereits abgehandelt.
Wenn man abwägt wie viel Komplexität für den Entwickler hinzukommt, wenn er plötzlich im Code mit Objekten umgehen muss, die nicht den Scope verlassen können bzw. das wechseln des Scopes explizit angegeben werden muss und welche, die das schon können, dann ist mir so ein explizites Konstrukt wie in Java schon lieber. Das RAII-Java-Beispiel zeigt doch nur interessante Einsatzmöglichkeiten von Java's neuem RAII artigem syntax sugar
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: RAII und Java

Beitrag von dot »

Chromanoid hat geschrieben:Wenn man dann aus verschiedenen Gründen doch einen GC einsetzt, wird RAII zu eine Art try-with-resources.
Aber eben eine die tatsächlich nicht nur Syntaxzucker ist und tatsächlich ohne dass man erst wieder alles mit try/finally Blöcken pflastern muss funktioniert...
Chromanoid hat geschrieben:Wenn man abwägt wie viel Komplexität für den Entwickler hinzukommt, wenn er plötzlich im Code mit Objekten umgehen muss, die nicht den Scope verlassen können bzw. das wechseln des Scopes explizit angegeben werden muss und welche, die das schon können, dann ist mir so ein explizites Konstrukt wie in Java schon lieber.
Es kommt eigentlich keine Komplexität hinzu, mit der man sich nicht sowieso befassen müsste, wenn man anständig designen will. Genau das ist die fundamentale Erkenntnis: Ein Garbage Collector reduziert die Komplexität eines Problems nicht, sondern verschleiert sie nur...
Zuletzt geändert von dot am 01.06.2012, 11:42, insgesamt 4-mal geändert.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Wenn ich hier RAII sagen, dann meine ich damit nichts anderes als die vielfältigen Variationen und Abstufungen von try-with-resources in Java bis hin zu deterministischer Lebenszeit von Objekten mit konsequenter logischer Konstruktion und Destruktion in C++. RAII beschreibt zunächst einmal das Konzept, Ressourcen durch Objekte (und deren Geltungsbereich, unterscheide hier von Lebenszeit wegen close()-Methode) verwalten zu lassen. Ob das durch zusätzliche Geltungsbereiche wie try-with-resources oder durch Geltungsbereiche im Rahmen deterministischer Lebensdauer geschieht, ist für mich hier erstmal zweitrangig.

Klar ist das etwas ungeschickt, weil RAII in Reinform eigentlich Transitivität und Kopplung von Ressource und Objektlebensdauer impliziert, aber eine begriffliche Differenzierung ist nicht ganz einfach, weil der Name RAII selbst in dieser Hinsicht ungenau und unglücklich gewählt ist. RRID (Resource Release is Destruction) würde es wohl besser treffen, dann könnten wir RAII (Resource Acquisition is Initialization) hier problemlos und unmissverständlich als Oberbegriff nutzen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

dot hat geschrieben:
Chromanoid hat geschrieben:Wenn man abwägt wie viel Komplexität für den Entwickler hinzukommt, wenn er plötzlich im Code mit Objekten umgehen muss, die nicht den Scope verlassen können bzw. das wechseln des Scopes explizit angegeben werden muss und welche, die das schon können, dann ist mir so ein explizites Konstrukt wie in Java schon lieber.
Es kommt eigentlich keine Komplexität hinzu, mit der man sich nicht sowieso befassen müsste, wenn man anständig designen will...
Das sehe ich anders. Bei D gibts da z.B. das "scope" Keyword, dass die Objekte dann auf den Scope der aktuellen Funktion bzw. des aktuellen Blocks beschränkt. Außerdem gibt es dann noch Scope-Classes die dann nur in lokalen Variablen benutzt werden dürfen. Ich finde das kann ziemlich undurchsichtig werden. (habe mir das eben mal aus dem Google-Cache der D-Seite rausgesucht, da irgendwie gerade alle Links kaputt sind) try-with-resources ist da schon eine ganz nette Lösung, die natürlich auch ihre Nachteile hat.

Ich sehe RAII ziemlich eng mit Stack und Scope verwoben und finde den englischen Wikipedia-Artikel zu RAII ziemlich einleuchtend. http://en.wikipedia.org/wiki/Resource_A ... ialization Dass try-with-resources im Grunde schon RAII ist finde ich nicht.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Chromanoid hat geschrieben:Ich sehe RAII ziemlich eng mit Stack und Scope verwoben und finde den englischen Wikipedia-Artikel zu RAII ziemlich einleuchtend. http://en.wikipedia.org/wiki/Resource_A ... ialization Dass try-with-resources im Grunde schon RAII ist finde ich nicht.
Zum Begriff RAII habe ich gerade eben ja schon geschrieben. Meine letzten Posts waren auch nicht gegen try-with-resources gerichtet, sondern gerade dafür, das Beste daraus zu machen. Und das ist dann wohl auch das Fazit. try-with-resources ist so viel RAII, wie du daraus machst (mit einer gewissen Obergrenze am unteren Ende der oberen Hälfte). ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

Naja für richtiges RAII fehlt es Java an Sprachmitteln. Und die gibt es imo deshalb nicht, weil das zum Einen zu hoher Komplexität führt (siehe http://zfx.info/viewtopic.php?f=4&t=2337&p=30851#p30850) und zum anderen weil RAII zusammen mit GC problematisch ist und wenig Sinn macht, da GC geführte Objekte eine undefinierte Lebenszeit haben, RAII aber eine an den Scope gebundene Lebenszeit voraussetzt. Der Grund ist nicht, wie du so schön am Anfang postuliert hast, dass sie es verkackt haben ;).
CodingCat hat geschrieben:
Chromanoid hat geschrieben:Naja, das hat ja alles seinen Grund. Mal eben so eine Möglichkeit einführen den GC zu umgehen ist keine gute Lösung. Mit der neuen try-with-resources Syntax bleibt das ganze wenigstens beisammen und man vertut sich weniger.
Nein, der GC wird in keinem Fall umgangen (bzw. wenn, dann ist das ein Implementierungsdetail). Es geht um den automatischen Aufruf der close()-Methode, und dieses Konzept haben sie mal wieder gründlich verkackt, siehe Post obendrüber.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Chromanoid hat geschrieben:Naja für richtiges RAII fehlt es Java an Sprachmitteln.
Ja, siehe Post obendrüber.
Chromanoid hat geschrieben:Und die gibt es imo deshalb nicht, weil das zum Einen zu hoher Komplexität führt (siehe http://zfx.info/viewtopic.php?f=4&t=2337&p=30851#p30850)
Das scope-Keyword ist doch nur eine andere Notation als try(...), und eine Scope Class stellt sicher, dass gewisse Objekte auch immer nur ordnungsgemäß in einem solchen Kontext Verwendung finden. Somit ist eine Scope Class nichts anderes als die Möglichkeit, sich selbst spezifischere try-Statements zu definieren (synchronized(...) { ... } ließe sich z.B. in D einfach als Scope Class umsetzen).
Chromanoid hat geschrieben:und zum anderen weil RAII zusammen mit GC problematisch ist und wenig Sinn macht, da GC geführte Objekte eine undefinierte Lebenszeit haben, RAII aber eine an den Scope gebundene Lebenszeit voraussetzt. Der Grund ist nicht, wie du so schön am Anfang postuliert hast, dass sie es verkackt haben ;).
Nochmal: Bindet man RAII nicht an die Lebensdauer, sondern an die Gültigkeitsspanne (oder angelehnt an Javas close-Terminologie den Öffnungszeitraum) eines Objekts, dann erhält man ein sehr mächtiges Werkzeug, das dem GC nicht in die Quere kommt. Genau das versucht das neue Java, aber hat es verkackt, weil immer noch keine Werkzeuge für transitive Ressourcenverwaltung, zusammengesetzte Ressourcen und die Übertragung von Ressourceneignerschaft zur Verfügung gestellt werden. Die letzten beiden Punkte lassen sich, wie wir gesehen haben, mit etwas Aufwand lindern. Alle drei Punkte ließen sich jedoch mit einem entsprechenden Ressourcen-Referenztypen geschickt erschlagen. Ein solcher Referenztyp würde obendrein die Komplexität des verlinkten Beispiels enorm reduzieren zu:

Code: Alles auswählen

class HeavyOnResources implements AutoCloseable {
   private ResourceReference<ResourceA> resA;
   private ResourceReference<ResourceB> resB; // optional, beliebig viele weitere
   // ...

   public HeavyOnResources(...) {
      resA = new ResourceA(...);
      resB = new ResourceB(...);
   }
}
Und wenn mir jetzt nochmal jemand kommt mit RAII erhöht die Komplexität ...

Und bevor es gleich wieder losgeht: Nach dem Wikipedia-Artikel ist das vielleicht kein RAII. Nach meiner Definition wäre das schon genügend RAII, um mit Java endlich einigermaßen vernünftig arbeiten zu können. Ich persönlich brauche zwar keinen GC, aber damit wäre Java zumindest soweit, dass man damit und mit etwas Umsicht sicheren Code schreiben könnte. (Umsicht, weil noch immer Gefahr besteht bei falscher Benutzung des try-Statements, ungeschützter Übergabe gerade geöffneter Ressourcen etc.)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: RAII und Java

Beitrag von Chromanoid »

Was du da haben möchtest, kannst du dir ganz leicht mit einem Annotation-Processor selbst bauen. Dennoch würde man deine vorgeschlagene Notation nur mit try-with-resources benutzen können. Für mich ist das kein RAII, aber wenn es dir reicht ist doch prima. Wenn du dann lieber Java programmierst, bau dir doch mal Spaßes halber eine Annotation @AutoClose inkl. Processor...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RAII und Java

Beitrag von CodingCat »

Chromanoid hat geschrieben:Was du da haben möchtest, kannst du dir ganz leicht mit einem Annotation-Processor selbst bauen. Dennoch würde man deine vorgeschlagene Notation nur mit try-with-resources benutzen können. Für mich ist das kein RAII, aber wenn es dir reicht ist doch prima. Wenn du dann lieber Java programmierst, bau dir doch mal Spaßes halber eine Annotation @AutoClose inkl. Processor...
Java hat noch genügend andere Verfehlungen, die mich davon abhalten werden, je ohne Grund auf diese Sprache zurückzugreifen.

Und willst du mir jetzt ernsthaft erzählen, das Problem bestünde nicht, weil ich die Sprache selbst fixen könnte? Es geht hier doch nicht um persönliche Projekte, es geht hier um eine strukturierte und sichere Programmierung, die nach Möglichkeit über lang zur gängigen Praxis in allen Bereichen werden sollte.

Und ich habe keine Ahnung, was du mit "Für mich ist das kein RAII" von mir willst. Ich versuche hier konstruktive Kritik an Java zu üben, was versuchst du?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Antworten