Java Problem, Kopie oder Referenz

  • ne kurze java frage.

    Code
    Hashtable h;
    
    
    public Enumeration blah() {
       Enumeration e = h.elements();
       h.clear()
       return e;
    }


    wieso ist die enumeration die returniert wird leer?

    Meine Vermutung waere das e nur ne referenz is und durch h.clear auch e geloescht wird. aber wie komm ich dagegen an? ich dachte eigentlich java macht immer ne kopie.

    mfg david

    I like Toast!

  • Generell wird bei Java nur ein Pointer übergeben, deshalb muss man explizit eine Kopie des Objektes erstellen, wenn man das ursprüngliche löschen will (sonst macht er dies mit dem referenzierten Objekt).
    Da Enumeration ein Interface ist, wird man das kaum per clone()-Methode (müsste dazu von Object abgeleitet sein) duplizieren können, mit der gesamten Hashtable müsste das jedoch reibungslos klappen.

  • muehsam =)

    also

    Code
    Hashtable h;
    
    
    public Enumeration blah() {
       Hashtable i = (Hashtable) h.clone();
       h.clear();
       return i.elements()
    }

    Wenn ich doch nur debuggen koennte, aber irgendwas stimmt auf meinem rechner nicht und ich hab keinen tau was :) auf jedenfall verhaelt er sich nicht so wie er soll.

    danke fuer den hinweis.

    gruss, david

    I like Toast!

  • Gehtnicht, gibt ne Nullpointerexception in folgender Zeile

    Code
    Hashtable h;
    
    
    public Enumeration blah() {
       Hashtable i = (Hashtable) h.clone(); //NullPointerException
       h.clear();
       return i.elements()
    }

    Hat noch wer nen tipp, ich will die enumeration retourgeben und dann die hashtable clearen.

    david

    I like Toast!

  • hi!

    sorry, i versteh dein anliegen nicht.

    eine enumeration (=aufzählung) verweist ja auf eine instanz. sprich, wenn du die instanz leerst, wird auf eine leere instanz ohne objekte verwiesen und somit wird dir der iterator auch nichts zurückliefern.

    zweitens versteh i generell deinen code nicht, was du damit bezwecken möchtest, wenn du nebstbei die hashtable leerst.


    lg

  • Zitat von davewood

    Gehtnicht, gibt ne Nullpointerexception in folgender Zeile

    Code
    Hashtable h;
     
    public Enumeration blah() {
    Hashtable i = (Hashtable) h.clone(); //NullPointerException
    h.clear();
    return i.elements()
    }



    Hat noch wer nen tipp, ich will die enumeration retourgeben und dann die hashtable clearen.

    david

    dein problem muss schon weiter vorne liegen.. mach mal

    Code
    if (h == null)
    System.out.println("h==null\n");



    als erste anweisung in deiner methode.

    lg michi

  • Erm *schaem*

    es handelt sich um nen vector und keine hashtable, klarerweise kann ich dann auch ned auf hashtable casten.

    danke fuer eure hilfe es hat sich somit erledigt :)

    david

    I like Toast!

  • der vollstaendigkeit halber.

    es handelt sich um nen UDP chatserver mit clients welche periodisch nachrichten pollen.

    Ich speicher die messages fuer jeden client in nem vector

    der server holt sich nun alle messages fuer den user mit der funktion blah() welch ein wirklichkeit getMsgs() heisst.

    diese funktion soll die enumeration retourgeben und danach alle messages leoschen weil ich sie dann nicht mehr brauche.

    david.

    I like Toast!

  • Unübeprüfte Annahme: In deinem ersten Beispiel hast du die Hashtable geleert, die Enumeration war davon betroffen.

    Bei diesem Code ...

    Code
    public Enumeration blah() {
    Hashtable i = (Hashtable) h.clone(); //NullPointerException
    h.clear();
    return i.elements()
    }

    ... wird nach dem Ende der Methode blah() die Hashtabelle i zerstört, weil keine Referenzen mehr auf sie vorhanden sind. Deine Enumeration, die aber offenbar von der Hashtable abhängig ist, versucht auf diese nun mehr nicht mehr existente Hashtable zuzugreifen und scheitert.

    Btw, wieso retournierst du nicht ein Array oder einen Container? Würde dir das Leben erleichtern.

  • Zitat von JohnFoo

    Bei diesem Code ...

    Code
    public Enumeration blah() {
    Hashtable i = (Hashtable) h.clone(); //NullPointerException
    h.clear();
    return i.elements()
    }



    ... wird nach dem Ende der Methode blah() die Hashtabelle i zerstört, weil keine Referenzen mehr auf sie vorhanden sind. Deine Enumeration, die aber offenbar von der Hashtable abhängig ist, versucht auf diese nun mehr nicht mehr existente Hashtable zuzugreifen und scheitert.


    Das entspricht aber nicht davewoods Fehlermeldung, da er die NullPointerException in der Zeile mit dem Typecast hatte.

    LG Michi

  • Zitat von michi204

    Das entspricht aber nicht davewoods Fehlermeldung, da er die NullPointerException in der Zeile mit dem Typecast hatte.

    LG Michi

    Sorry, hatte den Thread nicht ordentlich gelesen und lediglich ins Blaue geschossen.

  • hier ein paar anmerkungen, die du (vielleicht) noch nicht bedacht hast:

    a.) was passiert, wenn zwischen den Aufrufen von

    Code
    Hashtable i = (Hashtable) h.clone();

    und

    Code
    h.clear()

    vom client-thread eine neue message hinzugefügt wird? Hast du das in deinem code bedacht?

    b.) das ständige clonen des vectors wird ziemlich auf die performance schlagen.

    Das was du da machst ist genau dasselbe wie wenn du schreiben würdest:

    Code
    public Enumeration blah() {
      Vector i = h; 
      h = new Vector();
      return i.elements();
    }

    Warum nicht statt einer gewöhnlichen linearen liste (vector) eine queue verwenden: Auf der einen Seite werden vom client nachrichten hinzugefügt, und auf der anderen seite nimmt sie der server wieder heraus.

    Ausserdem ist eine verkettete Liste (LinkedList) hier wahrscheinlich besser als eine ArrayList, da du sehr viele einfügeoperationen hast aber nur wenig in der datenstruktur suchen musst.

    c.)
    Die Typen java.util.Vector/java.util.Hashtable/java.util.Enumeration sind eigentlich seit java 1.2. veraltet. Stattdessen wird allgemein empfohlen andere klassen vom typ java.util.List , java.util.Map und java.util.Iterator zu verwenden. Das moderne äquivalent zum vector ist z.b. java.util.ArrayList.

    Auch wenn die alten Klassen nach wie vor vorhanden (und auch in das Collectionframework eingebunden) sind, ist es doch vor allem bei dem Interface Enumeration besser, stattdessen den Iterator zu verwenden).

    siehe hierzu auch: http://java.sun.com/j2se/1.4.2/docs/guide/collections/

    lg, Benjamin Ferrari

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!