Casting zu unbekanntem Typ, wenn nur der Klassenname als String dieses Typs angegeben wird

8

Ich besitze derzeit eine Liste von Objekten (mit Java 1.3), und sagen wir, dass ich eines der von list.get (i) zurückgegebenen Objekte in einen Typ umwandeln wollte, von dem ich nur den Namen der Klasse as kenne ein Faden. Im Wesentlichen wie ich Objekt o = (Klassenname) list.get (i); Dabei ist Klassenname eine String-Variable eines Klassennamens.

Ich dachte, ich könnte (Class.forName (className)) list.get (i) verwenden, aber ich habe einen Syntaxfehler erhalten, der behauptet, dass ich ein Semikolon vergessen habe.

Leider, da ich Java 1.3 verwende, habe ich keinen Zugriff auf die Class.cast (Object) -Methode.

Wie heißt die Klasse, die beim Umwandeln in einen anderen Typ in Java 1.3 verwendet wird? Gibt es eine Methode, die mir den korrekten Typ, den ich brauche, mit einem String-Parameter des Klassennamens geben kann?

    
Paradius 26.01.2009, 18:46
quelle

5 Antworten

10

Worauf kommt es an, wenn Sie nur das Ergebnis dem Objekt zuweisen? Alles, was Sie erreichen würden, wäre eine Ausnahme, wenn es nicht die Schnittstelle / extend implementiert hätte oder die Klasse gewesen wäre oder nichts getan hätte, wenn sie es getan hätte.

Dafür ein einfaches:

%Vor%

ist ausreichend (und sauberer)

Wenn Sie die Reflexion verwenden sollten, um an die Felder / Methoden der Klasse zu kommen, ist das gut so

    
ShuggyCoUk 26.01.2009 18:53
quelle
5

Nein, und das ist in den meisten Sprachen nicht möglich.

Der Grund dafür ist, dass der Typ, in den umgewandelt werden soll, zur Kompilierzeit und nicht zur Laufzeit bekannt sein muss (was Sie gerade versuchen).

Wenn Sie darüber nachdenken, macht es Sinn, denn da die Variable ein beliebiger Typname sein kann, wie sollen Sie auf die verschiedenen Mitglieder zugreifen? Das können Sie nicht, es sei denn, sie sind in einem Basistyp / Interface definiert, den alle Instanzen implementieren. In diesem Fall sollten Sie nur das verwenden.

    
casperOne 26.01.2009 18:48
quelle
2

Ein Szenario, in dem dies erforderlich ist, besteht darin, die Typsicherheit mit einem Altsystem zu erzwingen. Angenommen, Sie haben ein Persistenzsystem wie Hibernate, das eine rohe List der Ergebnisse von einer "Finder" -Methode bereitstellt. Das Umsetzen dieses rohen List auf einen parametrisierten Typ führt zu einer ungeprüften Warnung, und wenn die Liste ein Objekt vom falschen Typ enthält, kann ClassCastException zu einem unbestimmten Zeitpunkt in einem entfernt verwandten Code ausgelöst werden. Es kann am besten sein, den Inhalt der Liste zu validieren, indem Sie einen Mechanismus verwenden, wie er vom OP vorgeschlagen wird.

Hier ist die Java 1.3-Version (ohne Generika):

%Vor%

In Java 5 und höher können Sie mit Generics etwas Ähnliches mit der Methode Class.cast() durchführen, um den Inhalt einer Auflistung zu verifizieren und die Verwendung einer Annotation SuppressWarnings zu rechtfertigen. In unserem Überprüfungsprozess wird das Unterdrücken einer Warnung ohne einen "Beweis", dass sie sicher ist, als Fehler gespeichert.

    
erickson 26.01.2009 20:02
quelle
1

Ich nehme an, dass Sie wirklich Folgendes schreiben wollten, anstatt Object auf der linken Seite zu verwenden. Ansonsten geht es nur darum zu prüfen, ob das Objekt in der Liste den richtigen Typ hat.

%Vor%

Nun, Java ist statisch getippt. Es ist nicht möglich, dass Sie ihm eine Zeichenfolge geben, und es gibt Ihnen den entsprechenden statischen Typ, so dass Sie ohne Casting gehen können. Auch bei Generics und Class<T>.cast wird der Typ des Darstellungsziels nicht durch eine Zeichenfolge angegeben, sondern durch das generische Typargument T , das zur Kompilierungszeit bekannt ist. Sie müssen manuell auf den richtigen Typ umwandeln oder den gebräuchlichsten Typ beibehalten (in Ihrem Fall möglicherweise Objekt).

Wenn Sie Class.forName(className) eingeben, erhalten Sie ein Objekt vom Typ Class zurück, das zur Laufzeit Informationen über den Typ enthält, damit Sie

ausführen können %Vor%

Aber die Besetzung will einen Typ - nicht irgendein Objekt. Deshalb hat der Compiler Ihnen gesagt, dass etwas mit diesem Code nicht stimmt.

Der statische Typ der von diesem zurückgegebenen Referenz lautet Object . Dies ist wichtig: Der dynamische Typ eines Objekts, auf das verwiesen wird, und der statische Typ der Referenz, die auf dieses Objekt verweist. Der dynamische Typ des Objekts ist das, was durch einen String "gesteuert" werden kann (indem Class.forName verwendet wird), aber der statische Typ des Verweises, mit dem Sie zur Kompilierungszeit arbeiten müssen, und das ist nur ein Beispiel ) verwendet, um Funktionen auszuwählen, die einander überladen, kann nicht durch eine Zeichenfolge bestimmt werden.

    
Johannes Schaub - litb 26.01.2009 18:51
quelle
0

Die Frage war beantwortet bereits, aber ich möchte hinzufügen, dass es etwas zweifelhaft erscheint, dass Sie eine Liste haben sollten, in der Sie verschiedene Arten von Objekten aufbewahren (in diesem Fall any) -Objekte, aber anscheinend möchten Sie Operationen für sie aufrufen, die für jeden Typ spezifisch sind ...

Was ist der Sinn dieser Sammlung? Haben die Instanzen, die Sie darin aufbewahren, nicht irgendwas gemeinsam - irgendeinen allgemeinen Supertyp, in den Sie sie einwerfen könnten?

    
Jonik 26.01.2009 19:06
quelle

Tags und Links