Testfrage bzgl. generic methods / Typparameter

Steve222

Mitglied
Hallo allerseits,

diese folgende Frage konnte ich leider nicht richtig beantworten:

-----------------
Given that CharSequence is an interface implemented by both String and StringBuilder classes, and then given the following method:

public <S extends CharSequence > S hepp( s) {
// INSERT HERE
}

Which of the following can be inserted at // INSERT HERE to compile and run without error?

a) return s;
b) return (Object) s;
c) return s.toString();
d) return new StringBuilder(s);
e) return (S) new StringBuilder(s);
f) return null;
------------------

Wer kann mir gut und verständlich erklären welche warum die richtige Antwort ist?

Viele Grüße
Steve222
 
Also, als erstes ist f) eine möglich richtige Antwort, "null" geht immer ;)
Desweiteren stört mich etwas, und zwar das vor dem Parameter('s') keine Klasse steht, ist das so beabsichtig oder evtl. Fehler bei Copy&Paste?
Wenn 's' zum Beispiel von Typ 'S' ist, würde a) gehen, wenn 's' aber zum Beispiel ein String ist, würde anstatt a) e) funktionieren.
Die Erklärung dazu ist eigentlich ganz einfach: mit "<S extends CharSequence >" deklarierst du sozusagen eine neues Interface das von CharSequence erbt(welches unter anderem von String und StringBuilder implementiert wird). Der Rückgabewert der Funktion ist von diesem Typ 'S'.
Wäre 's' jetzt vom Typ 'S' würde natürlich a) funktionieren. Wenn s aber ein String ist, würde nur e) (außer f) natürlich) funktionieren, da dort ein neuer StringBuilder erstellt mit dem String 's' als Konstruktor-Parameter und dann in 'S' gecastet. Dieser Cast funktioniert da, S von CharSequence abgeleitet ist, das StringBuilder implementiert.
ich hoffe ich konnte dir helfen.

Gruß
Matt
 
Hallo Matt,

und nochmals Danke.

Es ist mir sehr unangenehm, geschlampt zu haben. Ich bitte um Entschuldigung.
Ich hatte den Typparameter S in der Parameterlistebzw. Agumentliste weggelassen. Es sollte so lauten:

public <S extends CharSequence > S hepp(S s) {
// INSERT HERE
}

Mit Möglichkeit "d) return new StringBuilder(s);" erscheint die Meldung incompatible types.
Warum? Erstens gibt es einen Konstruktor StringBuilder(str) der einen String als Argument nimmt
und einen Konstruktor StringBuilder(cs) der ein CharSequence als Argument nimmt.
Zweitens heisst es <S extends CharSequence> was bei generics bedeutet, dass S auch ein Implementer von CharSequence sein kann und genau das ist doch die class String.
Zudem entstünde somit mit "new StringBuilder(s);" eine StringBuilder Instanz die auch zu S passt, weil
class StringBuilder ...implements CharSequence.

Wo ist mein Denkfehler?

Viele Grüße
Steve222
 
Hey, dann ergibt das ganze natürlich etwas mehr Sinn ;)
Ein Vorteil(manche sehen es auch als Nachteil an, ich nicht) von Java ist, dass es im Vergleich zu C++ zum Beispiel nur sehr wenige implizite Casts, soweit ich weiß nur bei Wrapper-Klassen und zwischen einigen primitiven Datentypen.
Das ist auch der Grund warum nur "return new StringBuilder(s)" nicht funktioniert. Logisch gesehen funktioniert es (da "implements CharSequence", etc pp), aber der Compiler weiß das ja nicht, er hält sich nur strikt an seine Regeln und sieht nen type mismatch. In so einem Fall kann der Programmierer schlauer sein und den StringBuilder exlipzit in eine andere benötigte Klasse casten("return (S) new StringBuilder(s)), was in diesem Fall auch in jeder erdenklichen Situation funktionieren wird.
Ich hoffe ich konnte dir damit helfen.

Gruß
Matt

P.S.: Explizite Casts sind natürlich nur mit Vorsicht zu genießen, also an den Stellen, wo man genau weiß, was man tut, ansonsten handelt man sich sehr schnell ne ClassCastException ein.
 
Hallo Matt,

nach meiner Info war nur a) und f) korrekt, aber man kann wie Du sagst auch e) dort einfügen. Dann
muss hepp() aber an eine CharSequence Variable zurückliefern.
In jeder erdenklichen Situation funktioniert das also nicht.

Viele Grüße
Steve222
 

Neue Beiträge

Zurück