Fehlerbehebung

Funkeyfreak

Aktives Mitglied
Moin,

ich bin derzeit am lernen für meine Objektorientierte und Funktionale Programmierung Klausur und bin dabei auf diese Aufgabe gestoßen:
https://gyazo.com/04c1204ff1293499d155deb69a4be405

Dass ist ein Übungsblatt von meiner Uni was ich versucht habe zu bearbeiten, jedoch leider ein/einige Fehler gemacht habe und ich nicht weiß wie ich diese Beheben soll.

Der Fehler der mir angezeigt wird ist nur im FruitTree vorhanden und lautet wie folgt:
java.io.NotSerializableException: Fruit
at java.io_ObjectOutputStream.writeObject0(Unknown Source)
at java.io_ObjectOutputStream.writeObject(Unknown Source)
at FruitTree.main(FruitTree.java:30)

Ich hoffe ihr könnt mir weiterhelfen

Code:
public class Fruit implements Comparable<Fruit>{
    
    String name;
    int gewicht;
    
    public Fruit(String name, int gewicht) {
        this.name=name;
        this.gewicht=gewicht;
    }
    
    public int compareTo(Fruit otherFruit) {
        
        if(this.gewicht < otherFruit.gewicht)
            return -1;
        if(this.gewicht>otherFruit.gewicht)
            return 1;
        return 0;
    }
}
Code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import java.util.TreeSet;

public class FruitTree {
    
    public static void main(String[] args) {
        
        TreeSet<Fruit> fruitTree = new TreeSet<Fruit>();
        
        fruitTree.add(new Fruit("Kiwi",5));
        fruitTree.add(new Fruit("Kirsche",1));
        fruitTree.add(new Fruit("Ananas",75));
        fruitTree.add(new Fruit("Zitrone",15));
        fruitTree.add(new Fruit("Grapefruit",44));
        fruitTree.add(new Fruit("Banane",55));
        fruitTree.add(new Fruit("Kirsche",2));
        fruitTree.add(new Fruit("Kiwi",8));
        
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO.txt"));
            Iterator<Fruit> it = fruitTree.iterator();
            
            
            
            while(it.hasNext()) {
            oos.writeObject(it.next());
        }
            oos.writeObject(null);
            
            
            
            ObjectInputStream ois = new ObjectInputStream (new FileInputStream("IO.txt"));
            
            Object readObject=null;
            TreeSet<Fruit> deserializedFruits= new TreeSet<Fruit>();
            
            do {
                readObject=ois.readObject();
                if(readObject !=null)
                    deserializedFruits.add((Fruit) readObject);
            }
            while (readObject!=null);
            
            it=deserializedFruits.iterator();
            while(it.hasNext()) {
                System.out.println(it.next());
                ois.close();
                oos.close();
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }

            
        }

        
        
        
    }
 

Funkeyfreak

Aktives Mitglied
Wenn ich mir das Javadoc durchlesen, dann heißt es ja eig dass die Klasse das Problem sein soll.
Also wie ich es verstehe die Klasse Fruit, aber ich verstehe die Fehlermeldung immer noch nicht richtig...

Es soll ja ein Iterator der Klasse Fruit erstellt werden und mit der while-schleife dann, solange der Iterator ein nächstes Element hat, alle Elemente in IO.txt geschrieben werden.

oos.writeObject(null); -> soll ja dann ja nochmal ein leeres Element am ende in die Datei IO.txt schreiben, wobei mir grad nicht einfällt warum man dass nochmal macht.
 

mrBrown

Super-Moderator
Mitarbeiter
Der Fehler sagt einfach nur aus, dass deine Klasse nicht das Interface Serializeable implementiert - sobald du das ergänzt klappt das :)
 

Funkeyfreak

Aktives Mitglied
Ich verstehe aber immer noch nicht wo ich das implementieren soll und warum es ohne dass nicht funktioniert.
Wenn ich "implements Serializable" bei FruitTree anfüge funktioniert es nicht und wo anders macht es keinen Sinn würde ich sagen (dachte evtl meinst du dass)

Ich verstehe das Probleme irgendwie immer noch nicht...

Trotzdem schon mal danke für die Hilfe ^^
 

Funkeyfreak

Aktives Mitglied
bei der Klasse fruit habe ich jedoch schon "implements Comparable<Fruit>" und ersetzen mit "implements Serializable" geht ja auch nicht da ich "implements Comparable<Fruit>" ja benötige für FruitTree. Wie muss/kann ich das dann einfügen?

Sitze grad übel aufn Schlauch sry
 
K

kneitzel

Gast
Wenn Du mehrere Interfaces implementierst, dann werden diese durch Komma getrennt. Also bei Dir:
Code:
public class Fruit implements Comparable<Fruit>, Serializable {
 

White_Fox

Top Contributor
Von Klassen kannst du nicht mehrfach erben. Das hat den Sinn, daß du z.B. eine Frucht nicht auch noch von Gemüse erben lassen kannst.

Aber Interfaces handhabt Javas anders. Klassenvererbung baut eine IST-EIN-Beziehung. public class Banana extends Fruit{} <- Banana ist eine Frucht.
Interfaces werden oft mit abstrakten Klassen gleichgesetzt, aber das ist Quatsch. Interfaces erweitern um eine Fähigkeit, eine KANN-AUCH-Option, wenn du es so willst. Beispiel: public class Tank extends GroundVehicle implements Swimable <- ein Panzer ist ohne Zweifel ein Landfahrzeug, das AUCH schwimmen KANN. Daher auch die allgemeine Javakonvention, Interfacenamen auf *able - *fähig - enden zu lassen. Der Panzer ist schwimmfähig.

Und das ein Objekt auch um mehrere Spezialfunktionen erweitert werden kann ist logisch kein Problem. Aber eine Frucht von einem Gemüse erben zu lassen, das ist logisch ein Problem und daher nicht möglich.
 

mrBrown

Super-Moderator
Mitarbeiter
Aber Interfaces handhabt Javas anders. Klassenvererbung baut eine IST-EIN-Beziehung. public class Banana extends Fruit{} <- Banana ist eine Frucht.
Interfaces werden oft mit abstrakten Klassen gleichgesetzt, aber das ist Quatsch. Interfaces erweitern um eine Fähigkeit, eine KANN-AUCH-Option, wenn du es so willst. Beispiel: public class Tank extends GroundVehicle implements Swimable <- ein Panzer ist ohne Zweifel ein Landfahrzeug, das AUCH schwimmen KANN. Daher auch die allgemeine Javakonvention, Interfacenamen auf *able - *fähig - enden zu lassen. Der Panzer ist schwimmfähig.
Wobei Interfaces auch eine „ist-ein“ Beziehung sind, bei *able halt verkürzt auf „ist *-fähig/bar“ ;)
 

Funkeyfreak

Aktives Mitglied
Ok, ich dachte ich müsste ne einfache toString(); Methode anfügen um die Ausgabe in was lesbares zu verwandeln aber funktioniert irgendwie nicht.

Jemand ne Idee wie ich es umwandeln kann? Kenne es eig nur dass man per toString Methode dass hinbekommt...

"Fruit@4dd8dc3
Fruit@6d03e736
Fruit@568db2f2
Fruit@378bf509
Fruit@5fd0d5ae
Fruit@2d98a335
Fruit@16b98e56
Fruit@7ef20235"
 
K

kneitzel

Gast
Der Ansatz ist richtig. Hast denn denn eine toString Methode zu Fruit hinzu gefügt? Zeig doch Mal den Code.
 

Funkeyfreak

Aktives Mitglied
Ok habe es jetzt doch hinbekommen:

In Klasse Fruit habe ich dass hinzugefügt:
public String toString() {
return "name: " + this.name + ", gewicht: " + String.valueOf(this.gewicht);
}

und in Klasse FruitTree habe ich bei der while-Schleife, bei dem System.out.println(it.next()); -> System.out.println(it.next().toString()); angefügt
 

Neue Themen


Oben