Weil ich diesen Samstag arbeiten muss, hier eine kleine Quizfrage um euch zu quälen: Kennt ihr einen Weg, wie man in Java auf uninitialisierte Attribute eines Objekts zugreifen kann? Bitte den Quellcode dazu posten. Ich kenne einen Weg, die Auflösung gibt es später. Bitte kein google benutzen, sondern auf eigene Lösungen kommen!
Alle Attribute werden per default inistialisiert (mit null oder je nach primitivem Typ vorgegebenem default). Uninitialisierte (lokale) Variablen gehen nicht durch den Compiler... also wenn dann bitte ein Beispiel. Oder meinst du das die Variablen den von dir vorgegeben (initial) Wert zum Zeitpunkt des Zugriffs noch nicht haben? Das Phnomen hatte ich auch schon das ein oder andere mal, trotzdem sind die Variablen initialisiert (nur nicht mit dem Wert welchen man zunächst erwartet)
>Alle Attribute werden per default initialisiert (mit null oder je nach >primitivem Typ vorgegebenem default). Genau das meine ich, es gibt trotzdem eine Möglichkeit, VOR dieser Initialisierung auf ein Attribut zuzugreifen. Viel Spaß beim Nachdenken!
Claudio H. schrieb: >>Alle Attribute werden per default initialisiert (mit null oder je nach >>primitivem Typ vorgegebenem default). > > Genau das meine ich, es gibt trotzdem eine Möglichkeit, VOR dieser > Initialisierung auf ein Attribut zuzugreifen. Viel Spaß beim Nachdenken! Und dann? Wie merkst du das dieser Zugriff wirklich unitilalisiert geschieht? Und was soll das überhaupt bringen? (Wenn es nicht sogar von der VM Implementierung abhängig ist...)
Hey, das ganze ist eine Quizfrage, muss also keinen Nutzen haben. Man kann aber durch Zuweisung an eine Variable, die anschließend erst initialisiert wird, schöne Fehler einbauen. Also sollte man das schon im Hinterkopf behalten.
Aber eine Zuweisung welche danach überschrieben wird ist doch kein Zugriff auf eine uninitialisierte Variable, daher ja meine Frage wie du erkennst das du auf eine uninitialisierte Variable zugreifst...
Naja, du weisst ja, dass Java eine Reihenfolge der Initialisierung vorgibt, z.B. zunächst die static Attribute, dann der static Block, dann die Instanzattribute, dann werden die Konstruktoren aufgerufen, am Anfang jedes Konstruktors der super-Konstruktor usw. Kannst du dich irgendwie in diese Reihenfolge reinhängen, und auf ein Attribut zugreifen, welches erst später initialisiert wird? Per meiner Definition ist dieser Zugriff dann uninitialisiert.
Claudio H. schrieb: > Kennt ihr einen Weg, wie man in Java auf uninitialisierte Attribute > eines Objekts zugreifen kann? Per JNI, wenn man die "Lücke" zwischen AllocObject und CallNonvirtualVoidMethod ausnutzt. Was die JRE dazu sagt weiß ich zwar nicht, aber den Zugriff auf uninitialisierte Felder kann ich da bequem explizit hinschreiben ;-) Stephan
Gast
#1588240
Das da gibt zunächst 0 aus, danach 42.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
Gast
#1588252
Übrigens gibt es hier unterhaltsamere Rätsel präsentiert von Joshua Bloch höchstpersönlich. http://video.google.com/videoplay?docid=9214177555401838409#
Stefan May schrieb: > Das da gibt zunächst 0 aus, danach 42. Claudio H. (Threadersteller) schrieb: > Weil ich diesen Samstag arbeiten muss Lass mich raten: Claudio musste nur deswegen Samstag arbeiten, weil ein durch ein derartiges Konstrukt entstandener Fehler dringend bereinigt werden musste... Hier findet man ein bisschen Diskussion zum Verhalten von Java und von anderen Programmiersprachen in diesem Fall (der dritte Beitrag von oben erklärt das Verhalten des Codes von Stefan): http://www.artima.com/forums/flat.jsp?forum=226&thread=113723 Ich persönlich finde übrigens das Verhalten von C++ besser, auch deswegen, weil ich es selbst erleben musste, dass das hier ausgenutzte Verhalten von Java zu schwer zu lokalisierenden, ekligen Fehlern führen kann. Gelegentlich findet man daher die Regel, dass Konstruktoren nur als "final" gekennzeichnete Methoden der eigenen Klasse aufrufen dürfen. Stephan
Läubi .. schrieb: > Oder meinst du das die Variablen den von dir vorgegeben (initial) Wert > zum Zeitpunkt des Zugriffs noch nicht haben? Hatte ich doch oben schon geschrieben... Dieser Zugriff ist aber eben nicht uninitialisiert, sonder du bekommst (korrekterweise) 0 zurück, das dies nicht deinem erwarteten Wert (42) entspricht ist doch wieder etwas anderes. Das Objekt oder die Variable wird schon initialisiert, nur dein davon abweichender Default wert wird erst zugewiesen wenn der Konstruktor durchlaufen wurde. Das ist ärgerlich wenn man es weiss aber durchaus ein vorhersehbares Verhalten. @Stephan M. Naja das Problem tritt nur auf wenn man mehrere Aufgaben im Kontruktor ausführt, was ich mittlerweile für mich persönlich als schlechten Stil deklariert habe
Gast
#1588594
Na dann. Ist zwar kein Java, sondern Standard-C, aber trotzdem schön:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Über letzteres bin ich auch schon böse gestolpert.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Gast
#1588734
Läubi Du hast natürlich recht, daß das kein Zugriff auf uninitialisierte Variablen ist. Der TO hat ja seine Definition von "uninitialisiert" wiedergegeben. Und zu C++: Sowohl in Java als auch in C++ gibt es böse Fallen, die sich nur durch "Best Practices" umschiffen lassen. Nicht umsonst gibt es zu diesem Thema sowohl für C++ als auch Java diverse Bücher, die man gelesen haben sollte. mfg, Stefan.
Smayfinger, du hast "meine" Lösung gefunden. Ich bin tatsächlich mal über dieses Verhalten gestolpert, auf meinem Entwicklungsrechner lief das wunderbar, der ContinuousIntegration Server hatte eine andere VM und ist abgestürzt. Das Problem in meinem Fall war ein Framework, welches massiv auf dem "Template Method" Pattern aufgebaut hat, und mich dadurch zu diesem Ansatz gezwungen hat. Hat noch jemand eine Quizfrage?
Gast
#1590605
Dieses Verhalten ist ganz klar definiert und ist ganz sicher "bad
practice".
> Hat noch jemand eine Quizfrage?
Ja, ein ganzes Buch voll. Siehe Link zum Vortrag von Joshua Bloch.
>Dieses Verhalten ist ganz klar definiert und ist ganz sicher "bad
practice".
Wenn man allerdings den Attributen nicht im Konstruktor, sondern inline
einen Wert zuweist, dann ist das Verhalten von VM zu VM unterschiedlich.
Also glaube ich nicht, dass das SO genau definiert ist.
Dass es Bücher mit Quiz-Fragen gibt, ist mir schon klar, nur macht das
Rätseln im Forum mehr Spaß!
Gast
#1590610
Klaus Wachtler schrieb:
>1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Ich schäme mich, hab ich doch glatt vertauscht... G
Gast
#1591304
Claudio Du irrst: http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44670 In Punkt 4 geht es um die Initialisierung der Instanz-Variablen. In §12.5 steht am Ende auch die Antwort auf Deine Quiz-Frage. Mich würde interessieren, mit welchen VMs Du das unterschiedliche Verhalten beobachtet hast. Und noch ein Puzzler hinterher (Achtung ist geklaut und nicht von mir):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Was wird auf System.out ausgegeben? a) 3 b) 1.0 c) wirft eine Exception d) etwas total anderes Hint: JLS §15.25 mfg, Stefan.
Gast
#1591321
Und ein C-Puzzler hinterher:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
Was gibt das Program aus? Achtung, ebenfalls geklaut und leicht abgeändert, wegen Forum-Spamfilter. mfg, Stefan.
Stefan May schrieb: > Was wird auf System.out ausgegeben? > > a) 3 > b) 1.0 > c) wirft eine Exception > d) etwas total anderes d) nämlich 3.0 Kenn ich schon :)
Gast
#1591369
Genau wegen dem "Kenn ich schon" ist das langweilig. :-P
Stefan May schrieb: > Und ein C-Puzzler hinterher: Jeder, der mal die Programme beim Obfuscated Perl Contest gesehen (oder gar zu verstehen versucht) hat, wird sowas NIE NIE NIE durch den Compiler jagen und dann ausführen, weil es umgefähr eine Bazillion Möglichkeiten gibt, ein 'system("rm -fr $HOME")' zu verstecken 8-) Andererseits scheinen Compiler langsam aber sicher einzuholen, vgl. das Posting "danni - Apr 05, 2008 - 02:36 PM" / "Post subject: RE: Re: RE: operand out of range" auf http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=61771&start=0 Das hat mich deutlich mehr erstaunt als diese ewigen Versuche, "hello, world!" möglichst kompliziert hinzuschreiben... Stephan
smayfinger, die JDKs waren Version 1.4.1, beide auf WindowsXP. Wenn man in der überschriebenen abstrakten Methode Werte an Attribute zugewiesen hat, gab es zur Laufzeit bei einem JDK eine Excpetion, das andere lief durch. Kann natürlich auch am Compiler gelegen haben.
Gast
#1592402
> gab es zur Laufzeit bei einem JDK eine Excpetion
Welche Exception war das genau?
In Java 1.4 und älter waren einige Patterns gebräuchlich, die nicht
funktionierten. Zum Beispiel das double-checked-locking. In Java 1.5
wurde daraufhin das Memory-Model gründlich poliert und klar definiert.
In 1.4 war das Verhalten tatsächlich abhängig vom verwendeten Compiler
und von der verwendeten JVM.
Von Angelika Langer gibt es einen netten Vortrag zum Java Memory Model,
welcher wirklich sehenswert ist.
mfg, Stefan.
Die genaue Exception weiss ich nicht mehr, war aber vielleicht eine NullPointerException.
Gast
#1593881
>die JDKs waren Version 1.4.1, beide auf WindowsXP. Wenn man in der >überschriebenen abstrakten Methode Werte an Attribute zugewiesen hat, >gab es zur Laufzeit bei einem JDK eine Excpetion, das andere lief durch. >Kann natürlich auch am Compiler gelegen haben. ich finde es lüstig wie die von Java gepriesene "Plattformunabhängigkeit" von der Wirklichkeit eingeholt wird :)
Filter schrieb: >>die JDKs waren Version 1.4.1, beide auf WindowsXP. Wenn man in der >>überschriebenen abstrakten Methode Werte an Attribute zugewiesen hat, >>gab es zur Laufzeit bei einem JDK eine Excpetion, das andere lief durch. >>Kann natürlich auch am Compiler gelegen haben. > > ich finde es lüstig wie die von Java gepriesene > "Plattformunabhängigkeit" > von der Wirklichkeit eingeholt wird :) Ich finde es lustig wie Leute ohne Fundierte Kenntnisse sich über scheinbare Makel andere Leute Arbeit amüsieren... Was hat bitte ein (möglicherweise) unterschiedliches Verhalten verschiedener JavaVM (IBM? Windows? Sun?) mit Plattformunabhänigkeit zu tun? Zumal beide auf WinXP liefen... Zumal noch nicht mal der genaue Fehler reproduziert werden könnte, da Source + genauere Umgebung nicht (mehr) zur Verfügung stehen...
Gast
#1594226
>> ich finde es lüstig wie die von Java gepriesene >> "Plattformunabhängigkeit" >> von der Wirklichkeit eingeholt wird :) >Ich finde es lustig wie Leute ohne Fundierte Kenntnisse sich über >scheinbare Makel andere Leute Arbeit amüsieren... nett, dass du ohne mich zu kennen, als jemand ohne "fundierte Kenntnisse" (und dann noch falsch geschrieben, bin heute mal so kleinlich :) hinstellst. nein, ich vertrete die Meinung, dass eine komplexe Sache auch dann komplex bleibt, wenn man ihr ein anderes Pelz überstopft.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.