Reflection + Cast

Hallo,

ich habe mal wieder ein wahrscheinlich simples Problem wo ich einfach nicht sehe wo mein Problem liegt.
Ich versuche durch Reflection einen String in einen Integer zu parsen (der in einem Object geschrieben wird). Das ganze mal einfacher dargestellt sieht folgendermaßen aus:

Code:
        String myInt = "123"; 
        try { 
                Class myClass = Class.forName("java.lang.Integer"); 
                Object newOb = myClass.cast(myInt); 
                System.out.println(newOb+" "+newOb.getClass().getName()); 
        } catch (ClassNotFoundException e) {  
                e.printStackTrace(); 
        }

Ich bekomme immer eine nette ClassCastException.

Ich habe es auch schon mit folgendem Tipp aus dem Forum versucht:
http://www.tutorials.de/forum/java-grundlagen/321233-problem-beim-variablen-class-cast.html
Allerdings ist bei mir der Typ in den ich casten will variabel (in meinem Beispiel Integer) und ich schiebe ihn nachher in ein Object.

Irgendwie scheine ich meinen Fehler zu übersehen, kann mir jemand mal auf die Sprünge helfen was ich falsch mache?

Danke und Gruß
meinereiner
 
Hi meinereiner,

ich lass mich gerne eines besseren belehren, aber ich weiß nicht, wie das gehen soll.
So was geht ja auch nicht:

Java:
String myInt = "123";
Integer newOb = (Integer) myInt;

Gruß
joschi
 
Hallo,

"direkt" casten kannst du hier nicht... das was du willst ist eher eine Typ Konvertierung. Dazu könntest du wie im Link gezeigt dynamisch die ValueOf Methoden oder die (String) Konstruktoren der entsprechenden Ziel (Wrapper)Typen verwenden.

Gruß Tom
 
Hallo,

und vielen Dank für die schnellen Antworten. Jetzt wo ihr das Beispiel entzerrt habt sehe ich auch eind as das nicht funktionieren kann.

@Thomas
Denke das du recht hast muss aber mal eine ganz doofe Frage loswerden:
Wie bekomme ich meine dynamische Klasse (myClass) in diese Zeil reingepresst:
Code:
double result = convert(o, Double.class);
bzw muss die bei mir ja so "in etwa" aussehen:
Code:
Object result = convert(o, myClass.class);

Gruß
meinereiner
 
Hi meinereiner,

in Deinem Fall würde das dann wohl so aussehen:

Java:
 Integer newOb = convert(myInt, Integer.class);

Gruß
joschi
 
Hi Joschi,

Danke für deine Antwort.

Mein Pronlem ist das der Wert den ich bekomme nicht immer ein Integer ist. Manchmal ist es auch ein Double oder String. Deswegen bin ich anfangs so auf die Reflectionschiene gekommen ...

Sorry wenn ich mich missverständlich ausgedrückt habe!

Gruß
meinereiner
 
Hi meinereiner,

ist doch kein Problem :)
Was ist denn Dein Input und Dein Output?

In Deinem Beispiel sollte ein String nach Integer gewandelt werden?
Was gibts denn noch für Kombinationen?

Gruß
joschi

P.S.: Vermutlich antworte ich heute nicht mehr, aber morgen schau ich wieder rein :)
 
Hallo,

na wenn das kein Problem ist kommen hier die Quellen:
String, Integer, Double, Long, Date, ... ;-)
Nein Spaß bei Seite. Ich ziehe die Werte aus einer Datenbank die ich vorher via Java reingeschmissen habe. Dabei habe ich auch den Typ (also z.B. java.lang.integer) mit eingefügt.`Beim rauholen wollte ich diese gerne wieder zurückwandeln.
Ich denke es beschränkt sich auf die ersten 3 Werte oben. Bei Date komme ich mit valueOf wahrscheinlich sowieso nicht weiter. Deswegen denke ich ich werde einfach die 3,4 Fälle nehmen und die einfach durch ein Switch-Case-Anweisung erstellen. Falls es doch mal andere Werte gibt habe ich eben pech gehabt. :suspekt:

Oder gibts noch eine elegantere Lösung?

Gruß
meinereiner
 
Hallo,

schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

import java.lang.reflect.Constructor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Random;

/**
 * @author Thomas.Darimont
 * 
 */
public class DynamicCastExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Object o = "1234";

		for (int i = 0; i < 100; i++) {

			Class<?> targetType = randomType();
			try {
				Object result = convert(o, targetType);
				System.out.println(targetType + " -> " + result + " "
						+ result.getClass());
			} catch (Throwable t) {
				System.out.println(t.getMessage());
			}
		}
	}

	final static Class<?>[] TYPES = new Class[] { 
	//		Boolean.class,
	//		Character.class,
			String.class,
			Double.class,
			Float.class,
			Short.class,
			Integer.class, 
			Long.class, 
			String.class,
			BigDecimal.class, 
			BigInteger.class };
	final static Random RANDOMIZER = new Random();

	private static Class<?> randomType() {
		return TYPES[RANDOMIZER.nextInt(TYPES.length)];
	}

	private static <T> T convert(Object value, Class<T> to) {
		try {
			// first try valueOf Method...
			return to.cast(to.getDeclaredMethod("valueOf",
					new Class[] { String.class })
					.invoke(null, value.toString()));
		} catch (Exception e) {
			// if that fails
			try {
				// try String based Constructor
				Constructor<T> constructor = to
						.getDeclaredConstructor(String.class);
				return constructor.newInstance(value.toString());
			} catch (Exception ee) {
				throw new RuntimeException(String
						.format("Conversion from %s to %s failed for value %s", value
								.getClass(), to,value));
			}
		}
	}
}

Ausgabe:
Code:
class java.lang.Long -> 1234 class java.lang.Long
class java.lang.Short -> 1234 class java.lang.Short
class java.math.BigInteger -> 1234 class java.math.BigInteger
class java.lang.Short -> 1234 class java.lang.Short
class java.lang.Short -> 1234 class java.lang.Short
class java.lang.Double -> 1234.0 class java.lang.Double
class java.math.BigDecimal -> 1234 class java.math.BigDecimal
class java.lang.Long -> 1234 class java.lang.Long
class java.lang.String -> 1234 class java.lang.String
class java.lang.Short -> 1234 class java.lang.Short
class java.lang.String -> 1234 class java.lang.String
class java.math.BigDecimal -> 1234 class java.math.BigDecimal
class java.lang.Integer -> 1234 class java.lang.Integer
class java.math.BigInteger -> 1234 class java.math.BigInteger
class java.lang.Integer -> 1234 class java.lang.Integer
class java.lang.Float -> 1234.0 class java.lang.Float
class java.lang.String -> 1234 class java.lang.String
class java.lang.Integer -> 1234 class java.lang.Integer
class java.lang.Float -> 1234.0 class java.lang.Float
class java.lang.String -> 1234 class java.lang.String
class java.lang.Short -> 1234 class java.lang.Short
class java.math.BigInteger -> 1234 class java.math.BigInteger
class java.lang.String -> 1234 class java.lang.String
class java.lang.String -> 1234 class java.lang.String
class java.lang.Short -> 1234 class java.lang.Short
class java.lang.Integer -> 1234 class java.lang.Integer
class java.lang.Integer -> 1234 class java.lang.Integer
class java.lang.Float -> 1234.0 class java.lang.Float
class java.lang.String -> 1234 class java.lang.String
class java.lang.Float -> 1234.0 class java.lang.Float
class java.lang.Double -> 1234.0 class java.lang.Double
class java.lang.String -> 1234 class java.lang.String
class java.lang.Double -> 1234.0 class java.lang.Double
class java.lang.String -> 1234 class java.lang.String
class java.lang.Float -> 1234.0 class java.lang.Float
....

Gruß Tom
 
Zurück