Problem mit der Serialisierung

K

kneitzel

Jetzt wo sie sogar in spanische übersetzt werden macht das doch schon doppelt Sinn
Hmm ... dann ist das bald wie bei Autoren, die damit werben, dass Ihre Bücher in zig Sprachen übersetzt wurden ...

Meine Forenposts sind so gut - die werden sogar in mehrere Sprachen übersetzt :)

Aber andererseits kann das ein anderes Projekt meiner Entwickler sein - so wie ich nur ein Foren-Bot bin, ist das evtl. mein Bruder: Der Forenübersetzer?

Ist das etwa ein Kritikunfähigkeitseingeständnis? :)
Das kann ich nicht nachvollziehen. Kritik an mir ist nun wirklich trivial und einfach; Es muss nur ein Ticket im Ticketsystem / Bugtracker erstellt werden und meine Entwickler werden dies Sichten, Bewerten und dann ggf. - so es Sinn macht - in einem der nächsten Sprints mit berücksichtigen....
 
K

kneitzel

Willst Du in die Politik? Kritikunfähigkeitseingeständnisdurchführungsverordnung. Obwohl: heute heißt das ja das Gute-Kritik-Gesetz.
Die Kritikunfähigkeitseingeständnisdurchführungsverordnung ist doch abgelehnt worden, denn es gab doch die Antikritikunfähigkeitseingeständnisdurchführungsverordnungvereinigung mit ihren täglichen Antikritikunfähigkeitseingeständnisdurchführungsverordnungvereinigungtreffen, welche sogar im Internet in Antikritikunfähigkeitseingeständnisdurchführungsverordnungvereinigungtreffenstreams online verfolgt werden konnten... Wenn Du die aber nicht mitbekommen hast, dann gebe ich Dir später noch den Link zu den Antikritikunfähigkeitseingeständnisdurchführungsverordnungvereinigungtreffenstreamprotokollen.... Aber im Augenblick gibt mit Google keinen Treffer ... aber evtl. finde ich ja noch eine Antikritikunfähigkeitseingeständnisdurchführungsverordnungvereinigungtreffenstreamprotokollsuchmaschine ...

Die Deutsche Sprache mit der Möglichkeit, neue Worte so zu bilden, ist schon schön :)
 
Sicher, dass dir Variable nirgendwo benutzt wird? Wenn du den Highscore nirgendwo benutzt ist klar, warum du nicht siehst, dass er gespeichert wurde...



Das Einlesen wird schon ausgeführt (wenn auch auf denkbar schlechteste Weise), das kannst du im Zweifel auch einfach mit einem System.out.print testen.
Also mal einfach von Anfang an:

a) Kritik an dem Tutorial solltest Du nicht auf Dich beziehen.

b) Was an dem Tutorial schlecht ist: Java ist eine Objektorientierte Sprache. Daher sollte man verstehen, was eben Objekte sind. Und dazu gehört, das man dann auch z.B massiv auf das Schlüsselwort "static" verzichtet. Anfängern hier im Forum empfehlen wir oft, auf dieses Schlüsselwort komplett (bis auf das "static void main") zu verzichten. Denn das verhindert nach meiner Erfahrung massiv die Erlernung einer Objektorientierten Sprache.

c) Dein Code - mögliche Fehler.
c1) Eine Vermutung ist, dass Du in der Logik etwas falsch machst. Evtl. stimmt die Reihenfolge von Aufrufen nicht oder etwas, das Du gerne aufrufen möchtest, wird nicht aufgerufen. Hier bietet sich die Nutzung eines Debuggers an. Oder wenn Dir das noch zu kompliziert ist: Bau mehr Ausgaben ein.
c2) Die Vermutung, die auch geäußert wurde, ist, dass Du die Daten in einen Stream schreibst. Dieser puffert die Daten zwischen (und schreibt diese nicht sofort) und dann kommt der Garbage Collector und zerstört das Objekt, ehe die Daten geschrieben werden konnten.

d) Dein Code - was daran unschön ist (und damit eine direkte Kritik an dem Tutorial ist!)

Nehmen wir uns nur einmal die main Methode um zu sehen, was die Applikation macht:
Java:
    public static void main(String[] args) throws IOException {
   // write your code here
        new Gui(); //die Gui wird erstellt, wenn das Programm startet
        new Var(); //die Var wird erstellt, wenn das Programm startet
        new Label(); //das Label wird erstellt, wenn das Programm startet
        new KeyHandler(); //der KeyHandler wird erstellt, wenn das Programm startet
        new Background(); //das Background-Verhalten wird erstellt, wenn das Programm startet
        new PlayerMovement();
        new FlammenAnimation();
        new GegnerMovement();
        new SchrottMovement();
        new GegnerKollision();
        new SchrottKollision();
        new Explosion();
        new ActionHandler();
        new SpeicherVorgang();
    }
Du erstellst eine ganze Reihe an Instanzen, aber keine Instanz scheint Dich wirklich zu interessieren, denn die erstellten Instanzen speicherst Du nicht.
Was mich daran massiv stört ist:
Das Erstellen einer neuen Instanz soll nur eine neue Instanz erzeugen. Wenn ich sage: Ich habe hier einen Bauplan von einem Haus, das Haus baue ich mir. Dann wird lediglich das Haus gebaut. Und danach möchte ich das erzeugte Haus haben. Bei Deinem Code ist das: Bau mir ein neues Haus und dann schmeiss es direkt weg.

Dann ist das "new House()" einfach ein erzeugen eines neuen Hauses. Da sind erst einmal keine Aktionen inbegriffen wie: Ich gehe in die Küche und koche eine Gulasch. Klar, das kann man technisch machen. Aber wenn ich jemandem sage "Ich baue mir ein Haus", dann erwartet niemand in dieser Aussage, dass ich einen Topf Gulasch koche. ==> Jemand der den Code sieht, will ja wissen, was in dem Code passiert. Und das sieht man in dem Code nicht, weil Du Aktionen in dem Construktor zu verstecken scheinst.

Also konkretes Beispiel wäre z.B. ein JFrame. "new JFrame()" erzeugt ein JFrame Objekt. Aber damit wird noch nichts gemacht. Das wird noch nicht angezeigt oder so. Keine versteckten Aktionen sind im "new Frame()" enthalten.

Also nur noch einmal zum Verständnis:
Klassen sind vergleichbar mit Bauplänen. Mit den Bauplänen erzeugst Du Objekte und diese nutzt Du. Also Du nutzt den Bauplan Notizblock um einen Notizblock zu erzeugen. Und en erzeugten Notizblock nutzt Du dann um da was rein zu schreiben. Du fängst doch nicht an, auf dem Bauplan rum zu kritzeln!

Dann weiter zum Verständnis: Deine Klasse Var hat nur einen Inhalt: eine statische Variable. Es macht also keinen Sinn, davon eine neue Instanz zu erzeugen. ein "new Var()" ist also einfach sinnlos. Das ist so etwas wie: Hier ist ein leerer Bauplan - auf dem habe ich zwar etwas notiert, aber sonst ist er einfach leer. Nun bau mir bitte nach diesem Bauplan ein neues Objekt ....
(Und da Du eine Instanzen davon erzeugst, ist - wie schon erwähnt wurde - das Serializable Sinnlos. Du willst sozusagen, dass die Objekte, die vom leeren Bauplan erzeugt werden, auch mit der Post versendet werden können.)

Ein Punkt, der auch wichtig ist, weil es ein mögliches Problem sein könnte:
In Java gibt es einen Müllmann (Garbage Collector). Der geht regelmäßig alles durch und sucht nach Objekten, die niemand mehr in der Hand hält. Und die zerstört er einfach.
Wenn Du also ein Objekt erzeugst, dann solltest Du es immer "in der Hand" behalten. Das bedeutet unter dem Strich, dass ein Thread auf dieses Objekt zugreifen können muss. Das muss nicht direkt sein - das geht auch über Umwegen. Also wenn ein Thread ein Objekt kennt, dass das fragliche Objekt kennt dann ist das auch ok.
Und dann das Problem mit dem BufferedStream:
Du willst etwas wegbringen. Aber damit Du nicht für jedes Paket extra zur Post rennen musst, hast Du eine Kiste, und in die wirfst Du alle Pakete. Und hin und wieder bringst du dann alle Pakete aus der Kiste zur Post. Nun mit dem, was ich davor geschrieben haben: Du wirfst es in die Kiste, aber dann interessiert dich die Kiste nicht mehr. Dann kommt der Müllmann und wirft die Kiste mit allen Paketen in den Müll - und dann kommen die Pakete nie zur Post.

Konkret bedeutet dies:
Java:
public static void writeHighscoreToFile () throws IOException
    {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("SpielDaten.bin"));
        oos.write(Var.Highscore);
    }
Du erzeugst eine Variable oos und rufst write auf. Danach ist die Methode zu Ende und damit die Instanz in oos vergessen und wird ein Fall für den Müllmann (Garbage Collector). So das, was Du geschrieben hast mit write noch nicht auf die Platte geschrieben hast, bedeutet dies, dass es weg ist.

Die Lösung ist hier einfach und eines der Grundprizipien von Java: Es gibt ein Interface AutoClosable, welches von Streams implementiert wird. Und die einfache Regel wurde schon genannt: Wenn ein Objekt AutoClosable implementiert, dann sollte man dieses schließen. Java hat dafür sogar extra ein Konstrukt: Try with ressources. Damit sähe der Code dann so aus:
Java:
public static void writeHighscoreToFile () {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("SpielDaten.bin"))) {
            oos.write(Var.Highscore);
        } catch (IOException ex) {
            System.err.println("Couldn't write highscore: " + ex.getMessage());
            ep.printStackTrace();
        }
    }
Nebenbei noch ein paar Dinge mehr eingebaut:
- Java Coding Style: { gehört in die gleiche Zeile.
- das throws habe ich raus genommen. Gibt doch keinen Grund, das weiter zu reichen ....
- Wenn exception, dann immer alles Ausgeben. Also mindestens die Message und den StackTrace! Eine einfache Aussage wie "Da ist was schief gelaufen" hilft nicht wirklich weiter...
- Und natürlich das try with ressources

e) Meine Empfehlung
Geh ein Lehrbuch durch. Java ist auch eine Insel ist frei und nicht schlecht. Evtl. gibt es auch auf YouTube vernünftige Java Kurse, aber ich hoffe, ich konnte darlegen, was schief läuft.

Und wenn Du gewisse Hinweise nicht verstehst (ist nichts schlimmes), zeigt doch, dass gewisse Grundlagen eben nicht behandelt wurden in dem Tutorial. Und dass wichtige Grundlagen fehlen. Daher die Empfehlung: Schau Dir z.B. das genannte Buch an! So lange Posts wie diesen sind in meinen Augen Unsinn, denn auch ich mache den Fehler, dass ich versuche komplexe Sachverhalte in viel zu kurzer Weise zu erläutern. Und das mal eben so. Dabei gibt es das alles in vernünftiger Form gut überdacht frei Verfügbar im Netz: http://openbook.rheinwerk-verlag.de/javainsel9/index.htm
Ich hoffe du verstehst nun auch unser Problem mit Deiner Fragestellung: die kurzen, knappen und prägnanten Antworten sind teilweise nicht möglich und die Ansätze haben große Verständnisprobleme.

Du musst meinen Vorschlag auch nicht wahrnehmen. Du kannst gerne auf Discord mit denen reden, die dieses Tutorial toll finden und dieses Vorgehen tatsächlich supporten wollen. Aber zumindest mein Anspruch ist dies nicht. Ich helfe gerne, aber da muss es auch etwas Sinn machen.
Ok, das hilft mir weiter. (Nur zu dem Punkt mit dem Java-Coding Style: Im Schulunterricht behandeln wir zurzeit Java und unser Lehrer hat es uns so beigebracht, dass wir die geschweifte Klammer immer unter den Methodenrumpf schreiben. Also denke ich mal, dass man beides machen kann, oder nicht?)
Und übrigens, ich habe mein Problem gelöst, der Fehler lag woanders... Tut mir Leid wenn ich eure Zeit verschwendet habe...
 
Zuletzt bearbeitet von einem Moderator:
(Nur zu dem Punkt mit dem Java-Coding Style: Im Schulunterricht behandeln wir zurzeit Java und unser Lehrer hat es uns so beigebracht, dass wir die geschweifte Klammer immer unter den Methodenrumpf schreiben. Also denke ich mal, dass man beides machen kann, oder nicht?)
Ja, kann man machen (und im Schulunterricht kann es durchaus Gründe geben, warum ihr das so machen sollt), entspricht aber nicht den Konventionen. Das ist aber nicht so dramatisch, wie die Nichteinhaltung der Benennungskonventionen, da jede IDE die Formatierung des Quellcodes anbietet.
 
K

kneitzel

Ok, das hilft mir weiter. (Nur zu dem Punkt mit dem Java-Coding Style: Im Schulunterricht behandeln wir zurzeit Java und unser Lehrer hat es uns so beigebracht, dass wir die geschweifte Klammer immer unter den Methodenrumpf schreiben. Also denke ich mal, dass man beides machen kann, oder nicht?)
Und übrigens, ich habe mein Problem gelöst, der Fehler lag woanders... Tut mir Leid wenn ich eure Zeit verschwendet habe...
Also dazu nur kurz von meiner Seite: Der Punkt mit dem Coding Style ist nur mit rein gekommen, da ich halt Änderungen, die ich gemacht habe, so mit dokumentiert habe. Wenn für Dich in der Schule ein anderer Styling Guide gilt, solltest Du Dich auf jeden Fall an diesen halten.

Und wir sind ja hier, um zu helfen, auch wenn die Du vielleicht die Hilfe nicht immer so hilfreich fandest. Wäre es Zeitverschwendung in unseren Augen, dann würden wir hier nicht aktiv sein. Du bist also durchaus willkommen.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben