Vererbung / Reflection

DEV

Grünschnabel
Hallo,

hab hier ein komisches Problem, das ich nicht verstehe. Gegeben ist folgender Code:

Code:
public class CombinedChart extends Chart
{
    private JPanel PANEL = new JPanel();
    private TreeMap<Integer, ChartModel> CHARTS = new TreeMap<Integer, ChartModel>();

    public CombinedChart(Chart chart)
    {
        this(chart, 1);
    }

    public CombinedChart(Chart chart, int weight)
    {
        super();
.....
    }
}

und

Code:
public class Chart extends ChartPanel
{
     public Integer addData(...)
    {
        .....

        try
        {
            Method m = this.getClass().getDeclaredMethod("set"+renderer.RENDERER, new Class[] {Integer.class});
            m.invoke(this, index);
        }
        catch(Exception ex)
        {
            Main.MSG("Chart::addData:catch("+ex.getLocalizedMessage()+")", Main.MSG_ERROR);
        }

        tuneChart();

        return index;
    }
}


Der Code ist natürlich hier stark gekürzt. Folgendes Problem tritt auf: Wenn ich ein Objekt CombinedChart habe und (über Umwege) in die Methode "addData" laufe, bricht mir das Programm im try/catch-Block ab mit nur folgender Meldung:

charts.basic.CombinedChart.setXYLineAndShapeRenderer(java.lang.Integer)

Die Methode gibt es in Klasse "Chart", allerdings nicht in Klasse "CombinedChart". Da aber die Klasse von "Chart" erbt, müsste das doch problemlos laufen, oder nicht? Der Abbruch passiert bei "m.invoke", es gibt die Methode die ausgeführt werden sollte und es sind alle Variablen korrekt belegt. Wenn ich die Methode, die per Reflection aufgerufen werden sollte manuell ausführe (this.xxxx), dann geht das astrein; scheinbar liegt das Problem irgendwo bei der Reflection.

Kann mir hier jemand einen Tipp geben? Bin jetzt nicht unbedingt neu in Java, aber das verstehe ich nun überhaupt nicht. Leider fand ich zu dem Thema auch keine Infos bei Google.

Danke und Gruß
DEV



EDIT:

Habe nun testweise die Methode die nicht ausgeführt wird mal in die Klasse "CombinedChart" aufgenommen und leite weiter zu "super"; das geht, ist aber nicht Sinn und Zweck der Vererbung denk ich mal. Kann mir das jemand erklären wo hier der "Bug" ist?

Danke,
DEV
 
Zuletzt bearbeitet:
Hallo,

danke für die Antwort und sorry, Vertipper, sollte natürlich die angehängte addData sein statt addMA.

Gruß
DEV
 
Ah ok, sorry, hätte mir auffallen sollen wenn ich aufmerksam drübergeschaut hätte... my Fault.

Zum eigentlichen Problem:
Ich bin mir nicht ganz sicher ob es das ist, aber es kann beim Einholen von Informationen über Methoden manchmal passieren, dass ein Type Mismatch entsteht, wo er eigentlich nicht passieren sollte. Es gibt sicher Leute die können dir das "Warum" besser erklären, aber die Abhilfe KÖNNTE sein, wenn du
Code:
Method m = this.getClass().getDeclaredMethod("set"+renderer.RENDERER, new Class[] {Object.class});
statt
Code:
Method m = this.getClass().getDeclaredMethod("set"+renderer.RENDERER, new Class[] {Integer.class});
probierst, also den Upper Bound angibst.
Jedoch: Keine Garantie!
Für weitere Fragen gerne verfügbar.
Gruß
 
Hallo,

danke, hab das eben versucht, bekomme dann eine "NoSuchMethodException", was mir logisch erscheint, da es diese Methode mit "Object" als Parameter ja nicht gibt.

Aber die Idee war gut, hatte mich schon gefreut beim ausprobieren :)
 
puh... äußerst schwierige Nuss. Also ich würde an der selben Stelle noch "int.class", alternativ "Integer.TYPE" ausprobieren, ansonsten bin ich da von meiner Seite her leider am Ende....!
 
Hallo,

danke. Hab alles versucht, kommt immer der gleiche Fehler. Irgendwie scheint hier Reflection die Vererbung nicht zu kapieren.
 
Nachtrag:

Habs wohl gelöst: Was hier nicht funktioniert ist die Methode "getDeclaredMethod". Warum das so ist verstehe ich nicht ganz. Habs getauscht durch "getMethod" und dann gings ohne Einschränkung. Wenn mir das noch jemand erklären kann, bin ich dankbar.

@Colinwood: Vielen Dank für deine Hilfe, dadurch bin ich auf die Lösung gestoßen.

EDIT: Wie kann man ein Thema als "gelöst" markieren?
 
Zuletzt bearbeitet:
Super!

Ich hab das währenddessen auch gefunden, hätte also den Methodenwechsel evtl. auch noch empfohlen, aber stark dass du es schon selbst gefunden hast. Dafür liefere ich dir jetzt den Unterschied der beiden Methoden nach:

Wenn wir englischsprachigen Ursprungs wären, wüssten wir beim Klingen des Worts "declared" wohl gleich, dass es im Sinne von Java ein Gegenteilwort zu "inherited" darstellt. Was nämlich im Endeffekt dazu führt, dass es zwei Methoden gibt, eine für sowohl vererbte, als auch deklarierte Methoden: getMethod(), und eine nur für deklarierte Methoden: getDeclaredMethod(). Und das erklärt dann wiederum, warum der ganze Spaß beim Vererben nicht funktioniert.
Zum Nachlesen: Java Reflection in Action
Viel Spaß beim weitercoden :)
 
  • Gefällt mir
Reaktionen: DEV
Merci!

Was declared bedeutet (also die Übersetzung) war mir klar, leider aber nicht, dass das in Bezug auf die Klasse selbst anzuwenden ist, also Ausschluss der Vererbung. Muss man auch erst draufkommen :)

Kannst du mir noch sagen, wie man ein Thema als gelöst markieren kann?

Vielen Dank und Gruß
DEV
 
Zurück