toString einer Klasse liefert nicht das was erwartet wird

Hallo

Ich habe
Eine Klasse Folge mit einer überschriebenen toString methode mit return “Hello World”.
Einen webservice mit der Methode gibFolge. Die Methode erzeugt ein neues Folge Objekt und gibt es zurueck. (return new Folge())
Ausserdem habe ich einen webservice client.

Kommen wir zum Servlet, im Servlet ruf ich die client Methode gibFolge welches ein Folge Objekt zurueckgibt.

beim

sysout(gibFolge().toString()); erwarte ich jetzt HELLO WORLD

Es kommt aber “org.client.Folge@2d82a06f”

Falls mir jemand folgen konnte, warum ist das so?

Uebrigens wenn ich eine Methode gibText() erstelle mit return HEllo World und dann

gibFolge().gibText(); aufrufe. dann bekomme ich HELLO WORLD
Es funktioniert nur bei toString nicht


    @Override
    public String toString() {
        return "HELLO WORLD"';
    }

Sollte aus dem Bereich Java EE nach Java Grundlagen verschoben werden.

Vielleicht ein Tipfehler, weil in deinem Geposten Code ist noch ein ’ mehr als da sein sollte

die Klasse mit der toString-Methode in jedem Fall mal kopieren, neuer Name, alle verrückten Superklassen und spezielle Konstruktoren usw. evtl. aufräumen,
mit main-Methode ein Objekt erstellen, geht toString()?

wenn nein, dann in der Tat nicht mehr Servlet-Problem, dann hätte das Thema gleich ausgeklammert werden können,
sauberes einfaches Testprogramm

wenn doch, dann liegt es ja vielleicht doch in irgendwas in J2EE :wink: , wobei ich mir nichts vorstellen kann,

verwende auch
System.out.println(„gleich kommt es:“);
System.out.println(objekt);

oder auch die String.valueOf()-Methode, die verwenden toString() ganz gewiss,
nicht dass du irgendwie mit Sonderzeichen eine ganz andere Methode definiert hast…
(mit kopieren Code geht es aber, vom ’ abgesehen)


gibt es auch nicht verschiedene Versionen der Klasse parallel? sind Libraries beteiligt die vielleicht nicht aktualisiert wurden?
definiere ein neues public Attribut testweise, nur wenn das abfragbar ist, dann die richtige Klasse im neuen Stand erwischt…

‚wenn ich eine Methode gibText() erstelle‘ klingt freilich schon überzeugend abgesichtert in diese Richtung…

erstelle auch eine Methode gibText(), die noch ein neues Wort (wiederum zur Unterscheidung von Alt-Versionen) + den Aufruf von toString() zurückgibt,
was kommt dann raus für gibText()-Ausgabe?

was macht das single quote da:

return “HELLO WORLD”’;

in deiner Klasse vor dem Semikolon?

ah, sorry, hatte unbenannt schon bemerkt

Hallo

Das ’ war nur ein Tipfehler. In der Klasse gibts den nicht.

Ja es gibt tatsächlich, zwei VErsionen. Eine im package org.modell. Das ist die Klasse die ich geschrieben habe und eine in org.client das ist eine automatisch generierte Klasse von Netbeans.

Das ist der Inhalt der generierten Klasse, und ich kann den Inhalt auch nicht ändern da bei jeden Kompilieren er sie neu erzeugt.

Die Generierte Klasse


import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java-Klasse für folge complex type.
 * 
 * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
 * 
 * <pre>
 * <complexType name="folge">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="summe" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         <element name="zahlenList" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "folge", propOrder = {
    "summe",
    "zahlenList"
})
public class Folge {

    protected int summe;
    @XmlElement(nillable = true)
    protected List<Integer> zahlenList;

    /**
     * Ruft den Wert der summe-Eigenschaft ab.
     * 
     */
    public int getSumme() {
        return summe;
    }

    /**
     * Legt den Wert der summe-Eigenschaft fest.
     * 
     */
    public void setSumme(int value) {
        this.summe = value;
    }

    /**
     * Gets the value of the zahlenList property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the zahlenList property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getZahlenList().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Integer }
     * 
     * 
     */
    public List<Integer> getZahlenList() {
        if (zahlenList == null) {
            zahlenList = new ArrayList<Integer>();
        }
        return this.zahlenList;
    }

}

Das Original von mir

 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.modell;

import java.util.ArrayList;


public class Folge {
    private  ArrayList<Integer> zahlenList;
    private int summe;

    public Folge() {
        zahlenList = new ArrayList<>();
        summe = 0;
    }

    public ArrayList<Integer> getZahlenList() {
        return zahlenList;
    }

    public void setZahlenList(ArrayList<Integer> zahlenList) {
        this.zahlenList = zahlenList;
    }

    public int getSumme() {
        return summe;
    }

    public void setSumme(int summe) {
        this.summe = summe;
    }

    public void addZahl(int zahl) {

        summe += zahl;

        zahlenList.add(zahl);

    }

    public String gibZahlenDerFolge() {
        String result = "";
        for (int z : zahlenList) {
            result += z + " - ";
        }
        return result;
    }

    
    public String getTextRepresentation(){
        return toString();
    }
    
    @Override
    public String toString() {
        return "Hello World";
    }

   

 

   
}

na und die Ausgabe sagt doch org.client,
in solche verrücken Frameworks kann man nicht unbedingt toString() kontrollieren,
gibText() vielleicht dagegen schon, wobei besser nach Bean-Sprach setgetXy(), evtl. mit Attribut xy gerichtet

Problem geklärt oder noch ein Weg für toString() von hohen Interesse?
ich selber wüßte wohl nichts, aber für andere im Moment unklar ob die Erkenntnis was geändert hat
(falls vorher schon bekannt dann sträflich nicht erwähnt)

Naja, es wäre zu klären warum die IDE überhaupt automatisch was erzeugt und warum dabei die überschriebene toString() methode nicht beachtet wird. Hast du diese Frage geklärt ergibt sich die Lösung von selbst.

…denn so ist es richtig, was da ausgegeben wird. :slight_smile:

Lässt du dir ein JaxB Object von Netbeans erzeugen? Sowas kannste dir doch selber schreiben, dazu musste nicht irgend welche Plugins anstoßen für. :slight_smile:

Sieht aus, als wenn die dynamische Bindung der Methode bei toString() nicht greifen würde, und zumindest hier Object#toString() aufgerufen werden würde, obwohl tS richtig überschrieben wurde.

Was meinst du mit Servlet? Das ist doch nur eine kleine(,) auf einem Server laufende App?

Dann noch was, was mich auch ärgert, tS kann zurückgeben, diese Klasse oder diese Klasse und nächste Klasse.tS(). Zusammengefügt(en) und Rekursion, mit dfs und root leafe usw.

Hast du dich schon entschieden, auf ewas geeinigt? (btw)

Grüße und gute Nacht

Ok, war ja nur ein Ansatz, da es ja nicht kopiert war hätte es ja sein können, das der Name der Funktion toString einen Typo gehabt hätte

Ja da haben wir dann ja wohl das Problem, du bindest in der Klasse, wo du Folge verwendest die Flasche Klasse ein (deine Generierte mit dem klassischen toString) und nicht die von dir erstellte Klasse mit dem überschriebenen toString ein. Also am besten mal den Import korrigieren, dann könnte es gehen.

@CB WTF schreibst du da? Er ruft ja gar nicht die überschriebene toString auf, sondern eine andere Klasse, wo natürlich das toString nicht überschrieben ist. Und ja ein Servlet ist eine Klasse, die auf einem Webserver läuft und anfragen von Clients beantwortet (kann man z.b. für REST Webservices verwenden)

Aus statischer Sicht wird immer tS aus Objekt zurückgegeben/aufgerufen; wenn sie überschrieben ist, aus dynamischer Sicht die überschriebene Methode. Dann wurde tS nicht richtig überschrieben. Defacto keine Möglichkeit, tS nicht aufzurufen, wenn sie überschrieben wurde. Obj#tS(), wie du ja weißt, gibt einfach nur den Namen und die Speicherstelle zurück, mit dem natürlich auch verglichen werden kann.

Also was ist das Problem an meiner Aussage? Weil ich mich damit auskenne?

ahh mit tS meinst du, meine Annahme, die toString Methode?

Um auch dir zu erklären was das Problem ist:

Es gibt eine Klasse Client.Folge und eine Klasse Model.Folge.
In der Klasse Model.Folge wird die toString Methode überschrieben und liefert einen frei erstellten Text zu rück.
In der Klasse Client.Folge wird die toString Methode nicht überschrieben und liefert deswegen den Identifier (Speicherstelle) zurück
Wird also die Richtige Klasse verwendet, wird auch die richtige Methode aufgerufen, wird die Falsche Klasse aufgerufen, die falsche Methode.

Wird Paketübergreifend vererbt? Unabhängig davon wird immer die richtige Methode aufgerufen, sie wird nur nicht auf dem richtigen Objekt aufgerufen.

Das tS() “aus einer falschen/anderen Klasse” gepostet/kopiert/rezitiert/wiedergegeben wurde, dafür kann ich nix. Schönen Abend.

Applaus, Applaus du hast das Problem verstanden (gelöst eigentlich schon seit dem 6.3.) kann der Thread als gelöst markiert werden?

PS: Das hat nix mit Vererbung oder sonst was zu tun

Das obliegt dem TO.

oh, habe ich in diesem Fall gemacht :wink:

mache ich häufig, wenn gewisse Zeit für Reaktion des Themenersteller verstrichen ist,
wenn Thema halbwegs als gelöst erscheint, besonders falls nebenbei niemand zu komischen Offtopic-Diskussionen am Ende angelockt werden sollte…

leider nutzen diese Funktion nur wenige User selber, besonders die neuen kaum, da unbekannt,

in diesem (auch nicht seltenen) Fall hat ZickZack trotz späterer Forum-Aktivität ja nichtmal mehr auf meine recht direkte Frage in Posting #6 reagiert…

Auch gut, wenn der TO nicht mehr reagiert.

Ja es kann als gelöst markeirtwerden, ich habe jtzt statt toString einfach getStringRepresentation selbst geschrieben mit dem Inhalt der toString. Damit geht das. Ohne das ich verstanden habe warume s mit toString nicht ging.

Es wird immer tS() der Klasse aufgerufen, deren Objekt du mit new erstellt hast. Ist in der Klasse tS() nicht überschrieben (geworden), dann tS() aus der darüberliegenden Klasse. So in etwa. Thema gelöst.