Java: Immer noch keine echten Templates?
-
Ich habe keine Vorurteile wie mach andere Personen (das ist keine Anspielung also bitte net das Flamen anfangen :))
Ich könnte mich aber auch umbenennen ... JengizS ... etwas gewöhnungsbedürftig - nee lieber docht nicht
-
soweit ich weis ist java die sprache, welche oop nach heutigen maßstäben zur perfektion gerieben hat,soweit, dass sich c++ da noch ne große scheibe von abschneiden kann.
???
Smalltalk war schon viel früher da und Javas OO-Fähigkeiten sind doch beinahe minimalistisch verglichen mit Smalltalk.Ich kann in Java wunderbar prozedural programmieren...
Ach du scheiße, was siehst du denn bitte als "wunderbar" an?
Jo, ich habs ja probiert. Aber jedesmal wenn ich versuche etwas in Java zu machen dreh ich durch...
Kenn ich. Java ist auch nix für mich.
Ja, aber es ging um OO Konzepte. Und das 'Problem' hierbei ist, dass viele Leute glauben dass Java deshalb besser sein muss als C++ weil es 'perfekt' OO ist. Was aber ein Blödsinn ist. 'echte' OO habe ich bei Ruby
Naja.
Es hängt an vielen Kleinigkeiten. zB komme ich mit C# vernünftig aus...
Uff, ich nicht wirklich.
Was ich aber sehr interessant finde ist C++/CLI. Was ich bis jetzt so gelesen habe ist ziemlich genial!
------------------------
BTW, Klassen sind nicht grundlage für OOP. Es gibt reine OO-Sprachen, die ohne Klassen auskommen. Die verfolgen dann das Prinzip der Prototype-Based-OO (Beispiel: Self).
Auch BETA hat nicht direkt Klassen aber man kann Pattern quasi als solche verwenden.
-
Wenn ich jetzt ausführe was mich persönlich an Java stört, dann leite ich damit nur einen flamewar ein.
Ich habe einen kleinen Webserver (mit Plugins für verschiedene Protokolle - implementiert habe ich diese aber nicht :p) in Java geschrieben.
Und es war für mich eher eine Qual. Wobei Qual natürlich übertrieben ist - aber ich kam mit einigen Konzepten einfach nicht klar. Dagegen habe ich meine Matura (Abitur) Arbeit in C# entwickelt - das lief das eigentlich ganz vernünftig. Natürlich stören mich auch hier einige Sachen, aber eben signifikant weniger als an Java.
Das will ich nur kurz angemerkt haben, nicht das jemand denkt, ich habe noch nix mit Java gemacht und habe bloss Vorurteile.
Aber man muss ja nicht mit jeder Sprache gut auskommen
Auf C++/CLI bin ich aber auch extrem gespannt.
Und BETA muss ich mir mal langsam wirklich ansehen... steht seit ewigen Zeiten auf meiner 'Todo' Liste.
@Helium:
mit 'perfekt OO' meine ich das OO von 'Java ist perfekt OO' - und nicht Objekt Orientiert wie ich es sehe.Wenn man Java als 'perfekt OO' bezeichnet, muss Ruby 'perfekter OO' sein - denn dort ist alles ein Objekt.
Für mich persönlich haben 'Objekte' ansich nichts mit OOP zu tun. Für mich ist OOP mehr ein Konzept, zudem ich keine Klassen und Objekte im herkömmlichen Sinn brauche (obwohl es mit ihnen oft wesentlich einfacher, schöner und besser ist) - ich kann mir 'Objekte' zB auch gut als Handles vorstellen.
-
Shade Of Mine schrieb:
Wenn ich jetzt ausführe was mich persönlich an Java stört, dann leite ich damit nur einen flamewar ein.
Wenn du begründete Kritik äußerst, dann läßt sich immer darüber reden ohne, dass es eskaliert. Oder haben deine Kritikpunkte keinen nachvollziehabren Hintergrund?
-
Shade: sehe ich genauso wie Gregor. Speziell weil ich ja selber aus der C++ Ecke komme und absolut nicht der meinung bin das Java "besser" als C++ ist.(Auch nicht als C#). Also mich würde es schon sehr interessieren was dich stört.
Ich versteh zum beispiel nicht was du mit "Konzepten" meinst nicht.
Weil in dem Bereich unterscheiden sich C# und Java nicht soweit voneinander.Stimmt - ich komm mit ruby nicht so besonders gut aus - eigentlich komm ich mit ruby gar nicht aus - aber was solls
man kann auch wunderschoen Objektorientiert in C programmieren - mit function pointern und allem drum und darn. Das waren noch zeiten.
So ne mischform aus OOP und modularer/strukturierter programmierung.gomberl
Nur zur Info:
Ich hab mein Matura - Spezialgebiet in C++ geschrieben (COM / DCOM) - da war das .Net gerade in der Beta heraussen. War ganz lustig. Hab dann auch vergleich mit CORBA und RMI/EJB gemacht.
-
Gregor schrieb:
Wenn du begründete Kritik äußerst, dann läßt sich immer darüber reden ohne, dass es eskaliert. Oder haben deine Kritikpunkte keinen nachvollziehabren Hintergrund?
Nachvollziehbar? Für mich schon, aber jeder Javaianer mit dem ich bisher darüber gesprochen habe, dachte anders
Ich mag zB die 'checked Exceptions' nicht.
siehe auch: The Trouble with Checked ExceptionsDass socket.close() eine Exception wirft mag ich auch nicht.
Die Threads mit dem Interface Runnable, finde ich in C# besser gelöst -> DelegatesDann mag ich das Konzept von C# und Java nicht, dass ein Objekt 'undefiniert' sein kann (NULL Pointer Exception). Ich habe gerne alle Objekte in einem 'funktionierenden' zustand.
Generell finde ich die Exception sehr komisch gelöst. Alles wirft ne Exception - auch wenn es IMHO nur ein simpler 'Status' ist. zB EOFException - EOF ist IMHO eben kein Fehler und schon garnicht eine 'Ausnahme'.
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...
Da finde ich D sehr interessant: ich kann die 'unwichtigen' Resourcen wie zB Speicher dem GC überlassen - denn da ist es mir ja egal wann er freigegeben wird. Aber zB eine DB Verbindung oder ähnliches würde ich gerne nur solange offen lassen wie nötig. Denn ich will die DB ja nicht sinnlos warten lassen... Da mache ich das Objekte dann 'auto', sprich es wird zerstört wenn es out of scope geht.
Und Operatorenüberladung fehlt mir auch gewaltig. Ich kann mich einfach nicht an
i.add(5);
gewöhnen. Ich weiss dann nie, returned add jetzt ein neues Objekt, oder ändert es i?Die Artikel auf www.aritma.com fand ich da auch sehr interessant. Vorallem die Artikel mit Bruce Eckel und Anders Hejlsberg über das Design von .NET
Wie man sieht sind die meisten Argumente ja auch oft 'pro Java' Argumente (wie zB: GC kümmert sich um alles, operatoren überladung macht die Sache unnötig komplex,...). Mir ist schon klar, dass viele Leute Java so gut finden wie es ist. Nur ich gehöre halt nicht dazu.
Und ich hoffe es gibt jetzt keinen Flamewar...
-
'checked Exceptions': find ich persönlich gut speziell bei der architektur erstellung - geschmacksache
Dann mag ich das Konzept von C# und Java nicht, dass ein Objekt 'undefiniert' sein kann (NULL Pointer Exception). Ich habe gerne alle Objekte in einem 'funktionierenden' zustand.
dasselbe problem hast du aber in C++ auch. ein pointer auf ein objekt kann ja auch irgendwohin zeigen wenn er nicht initialisiert wurde.
Und wenn du eine referenz auf ein objekt hast und jemand anderer gibt den speicher dieses objektes frei dann hast du sogar bei einer referenz einen undefinierten zustandBei den Exceptions geb ich dir recht - die EOFException ist eines der besten beispiele dafuer
warum keine Destruktoren?
finalize ist quasi der java destruktor (die methode wird vor dem destruktor aufruf von der garbage collection aufgerufen)
bei db verbindungen hast du die close methode die es dir ermoeglicht die connection zu beenden. das objekt wird dann freigegeben sobald der GC es sammelt.
Operatorenueberladung: Das fehlt mir auch. Aber es stimmt schon das die operatoren ueberladung nur gut fuer denjenigen ist der sich intensiv damit beschaeftigt. fuer maintanence in einem system ist das ein horror.
also im endeffekt verstehe ich deine probleme (bis auf die destruktor problematik) - aber so das es mich in den wahnsinn treiben wuerde sind diese probleme doch nicht
lg
gomberl
-
gomberl schrieb:
finalize ist quasi der java destruktor (die methode wird vor dem destruktor aufruf von der garbage collection aufgerufen)
Ist es denn garantiert das finalize aufgerufen wird? AFAIK ist es das nicht.
Und das macht finalize irgendwie sinnlos... bzw. unnutzbar für 'teure' Resourcen wie eine DB Verbindung.bei db verbindungen hast du die close methode die es dir ermoeglicht die connection zu beenden. das objekt wird dann freigegeben sobald der GC es sammelt.
Und genau das stört mich. Weil es IMHO das Exception Konzept aushebelt.
Ich will ja garnicht auf alle Exception reagieren... Ich will die Exceptions dort behandeln wo ich sie behandeln kann - und das cleanup will ich dem Compiler überlassen. Da habe ich oft sehr viel Fehlerbehandlungscode in der Funktion - das erinnert mich manchmal an C, da habe ich auch immer sehr viele Fehler lokal behandelt.
Natürlich nicht immer - wie gesagt bei Speicher macht der GC einen super Job. Er achtet darauf dass nicht geswappt werden muss und ob jetzt 50 oder 70% des RAMs belegt sind, ist mir egal. Da ja nur das swappen teuer ist.
Aber bei DB Verbindungen oder ähnlichen 'seltenen' Resourcen hätte ich eben gerne ne Möglichkeit zu wissen, dass die Resource freigegeben wird.
Operatorenueberladung: Das fehlt mir auch. Aber es stimmt schon das die operatoren ueberladung nur gut fuer denjenigen ist der sich intensiv damit beschaeftigt. fuer maintanence in einem system ist das ein horror.
Hast du da mal so ein 'Horror Beispiel'?
Ich finde ein i.add(7); ist ein größere Übel.
Ich habe das mit den Problemen mit Operatorenüberladung noch nie kapiert.
Für mich ist
a+b;
nix anderes als
add(a,b);
wobei man keine Namensprobleme hat. Denn add(a,b); ist ja noch logisch.
Aber was ist a.add(b); ?
Da fängt es an, dass es aufeinmal ein add und ein append gibt - op+ und op+=Ich kenne diese Problematik nur von PHP - und da gibt es quasi keine 'value objekte' - aber dennoch muss ich öfters mal in die Doku schaun, wenn ich ein b) sehe...
-
Shade Of Mine schrieb:
Aber bei DB Verbindungen oder ähnlichen 'seltenen' Resourcen hätte ich eben gerne ne Möglichkeit zu wissen, dass die Resource freigegeben wird.
Und das ist in Java und C# allgemein gesagt solche methode:
.dispose() .free() .close()
-
Zeus schrieb:
Shade Of Mine schrieb:
Aber bei DB Verbindungen oder ähnlichen 'seltenen' Resourcen hätte ich eben gerne ne Möglichkeit zu wissen, dass die Resource freigegeben wird.
Und das ist in Java und C# allgemein gesagt solche methode:
.dispose() .free() .close()Darum 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.
Wenn ich also 3 mal vergesse Speicher freizugeben, kostet es mich vielleicht ein 1MB Memory Leak. Das ist natürlich doof - und deshalb finde ich GC ansich ja nicht schlecht - aber 1MB ist verkraftbar.
Wenn ich aber zuviele DB Verbindungen die unnötig offen sind, können tödlich sein - oder zumindestens bremsen sie das System. Gerade hier ist es wichtig, dass ich garantiert nicht vergesse die Verbindung freizugeben.
In C++ habe ich Destruktoren die das für mich übernehmen - denn jedes DB Objekt muss, wenn es nichtmehr gebraucht wird, die Verbindung frei geben.
Der Compiler weiss das aber am besten -> wenn es out of scope geht, brauch ich es nicht mehr - hier gibt es natürlich unterschiede zwischen Resourcen wie Speicher und DB Verbindungen. Deshalb denke ich auch, dass der C++ ansatz mit: immer Dtor auch nicht ideal ist. Ich mag deswegen den D Ansatz: ich kann mir aussuchen ob der GC kollektet wann er will, oder ob das Objekt gekillt wird, wenn es out of scope geht.
Natürlich muss ich dann selber aufpassen, dass es keine Referenzen mehr auf das Objekt gibt...
-
RAII ist schon toll, aber Java Programmierer kennen es vielleicht gar nicht. Deswegen bekommst du auch ständig solche antworten, wie es gibt doch 'ne close Methode ....
-
Ist es denn garantiert das finalize aufgerufen wird? AFAIK ist es das nicht.
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.
wie bereits Zeus sagte haben solche "teuren" objekte dafuer methoden.
close() zB schliesst eine connection. dieses connection objekt hat jetzt keine verbindung mehr mit der DB. das heisst du weisst das dein connection objekt zu ist. es wird nun aber nicht gleich aus dem speicher genommen - erst wenn der GC druebergeht.Und genau das stört mich. Weil es IMHO das Exception Konzept aushebelt.
den zusammenhang verstehe ich jetzt nicht. was hat das closen einer connection mit dem exception konzept zu tun.
das du nicht auf alle exceptions reagieren willst ist dein bier.
ich finde checked exceptions gut im architektur sinne und wenn ich das gut plane dann weiss ich auch welche methoden welche exceptions werfen.
man sollte zB in architektur entscheidungen immer schauen das man Basisklassen exceptions wirft um darauf dann spezialisierte exceptions aufzubauen. Ich kann dann die exceptions einfach durchreichen. das sollte mir aber schon von anfang an klar sein.
ich behandle zB fast keine Exceptions in methoden sondern habe meinen eigenen Exception handler der das fuer mich macht.Aber bei DB Verbindungen oder ähnlichen 'seltenen' Resourcen hätte ich eben gerne ne Möglichkeit zu wissen, dass die Resource freigegeben wird.
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 werdenHast du da mal so ein 'Horror Beispiel'?
klar hab ich eines
ein bekannter von mir hat eine zeitlang mit mir bei einer firma gearbeitet.
als ich dann dazu kam seinen C++ code zu debuggen musste ich mich erst einmal ein paar stunden in seine gesamt klassenstruktur einarbeiten (ist ja normal) und am naechsten tag habe ich dann mindestens genausoviel zeit damit verbracht zu checken was denn nun A + B intern bedeutet.
das problem auf das ich hinaus will ist das die lesbarkeit absolut 0 ist bei operatorenueberladung fuer jemand der sich neu einarbeitet.
wenn ich bereits erfahrung mit dem system und den operatoren habe dann ist es simpel. ich weiss was was tut und wie was zusammenhaengt. hoffentlich weiss ich was es im hintergrund ca tut. daraufhin ist es schneller im schreiben und auch schneller beim lesen.
Nur darf man halt nicht davon ausgehen das ich immer wen parat habe der sich damit auskennt. legacy systeme und enterprise software kann schon mal 10-15 jahre im betrieb bleiben. und seien wir uns ehrlich. die chance das ncoh wer nach 10 jahren im betrieb ist der sich damit auskennt ist relativ gering. speziell wenn das system von einer externen firma uebernommen wird, die wartung jedoch nach einer einschulung intern gemacht wird.es stimmt wohl das a+b nix anderes als add(a,b) ist
aber was ist add(a,b) fuer 2 objekte ?? was passiert hier?a.add(b) ist einfach das ist ein a+=b (zumindest sollte es sein laut eines alten handbuches das ich nutze)
man sollte naemlich solche operationen immer auch statisch haben
mit Klasse.add(a,b)aber ich muss auch in die doku schauen wenn ich in c++ ein Object1 + Object2 sehe
- zumindest wenn ich wissen will was das ding genau machtich hoffe du siehst was ich meine
gomberl
-
Was du an den Nullpointern schlecht findest, ist mir ein Rätsel. Manchmal braucht man das halt einfach, dass ein Pointer gerade auf nichts zeigt. Und immerhin kann er nicht undefiniert sein, und du kannst überhaupt nicht irgendeinen Muck damit machen. Wenn du es wie eine C++ Referenz benutzen willst, dann kannst du ja die Referenz final machen.
Und wenn du deine Exceptions von RuntimeException ableitest, dann musst du sie nicht in der throws-Listen angeben, dann hast du es so wie in C++.
Macht ja auch manchmal Sinn, sonst würde ja jede Methode eine IndexOutOfBoundsException werfen, wenn du dort mit Arrays arbeitest. Aber in manchen Situationen ist das schon sehr sinnvoll, dass der Compiler darauf aufpasst, dass man jeden Fall behandelt. Safety First.Und evtl. interressieren dich noch:
System.runFinalization(); System.runFinalizersOnExit(true);
@Helium: Das war eindeutig ein Flame-Versuch.
-
@Helium ... komm nicht mit vorurteilen ....
Naja ich kenne RAII wiklich nicht !Nun ich kenne Shade's Argument ist ja auch richtig, bloss ich finde es nicht schlimm, dass das so gelöst würde.
Viel schlimmer was mich an Java nervt ist expliziertes Exceptionshandling, das finde ich in C# besser gelöst, und die Standardmässige public virtual deklarierung von Members - ja ich weiss, dass es so gesagt nicht richtig ist - C# sind Members private, finde ich viel praktischer ...
Also in Endeffekt finde ich viels in C# besser gelöst als in Java... bloss C# und NET sind nicht wirklich Platformunabhängig.
Alles ne Geschmacksache^^
-
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.