2010-12-11 11 views
1

Edit: Dies wurde seither gelöst. Danke an alle, die geholfen haben. Der Aufruf der Methode nach dem Umsetzen des Objekts als korrekte Wrapper-Klasse hat funktioniert. Aber String.valueOf() ist viel, viel einfacher, den gleichen Effekt zu erzielen.Dynamische Umwandlung in Primitive in Java

Hello--

Was ich versuche möglich sein kann, nicht einmal zu tun. Ich habe jetzt ein paar Stunden damit verbracht, verschiedene Dinge zu recherchieren und zu experimentieren, also dachte ich mir, ich würde endlich fragen, ob jemand weiß, ob das überhaupt möglich ist.

Ist es möglich, mithilfe von Reflection einen Wrapper für ein primitives Element eines unbekannten Typs als primitives Element dynamisch zu generieren?

Ich versuche im Grunde, eine generische toString-Funktion zu erstellen, die die Umwandlung von jeder Art von Primitiven in eine Zeichenfolge verarbeiten kann. Solch ein scheinbar einfaches Ding ist frustrierend schwierig (und ich bin mir bewusst, dass ich jeden Typ testen könnte, um zu sehen, ob es vom Typ Wrapper.class ist und es spezifisch ausgibt, aber an diesem Punkt verfolge ich das nur aus Sturheit).

Folgendes löst eine ClassCastException aus. Die primClass-Klasse scheint die richtige zu sein (gibt "int" beim Drucken von primClass.getName()).

private String toString(Number obj){ 
    String result = ""; 
    try{ 
     Class objClass = obj.getClass(); 
     Field field = objClass.getDeclaredField("TYPE"); 
     Class primClass = (Class)field.get(obj); 
     Method method = objClass.getMethod("toString", new Class[]{primClass}); 
     Object args = new Object[]{primClass.cast(obj)}; 
     result = (String)method.invoke(null, args); 
    }catch(Exception ex){ 
     //Unknown exception. Send to handler. 
     handleException(ex); 
    } 
    return result; 
} 

Also bin ich ein bisschen ratlos, wirklich. Hat jemand Ideen? Jede Hilfe würde sehr geschätzt werden.

+1

'toString' Methoden auf' Double, Long, ... 'tun Sie nicht was Sie wollen? – khachik

Antwort

0

Vielleicht möchten Sie sehen Apache Commons Lang, vor allem ToStringBuilder.reflectionToString(). Selbst wenn Sie keine Abhängigkeit nur für ein toString() einführen möchten, ist es Open Source, so dass Sie sich die Implementierung ansehen können.

method.invoke akzeptieren die Wrapper-Typen anstelle der Primitives-Typen.

+0

Oh. Scheisse. Ich kann es nicht glauben. Ich dachte, ich hätte das ausprobiert und es hat nicht funktioniert, aber ich muss gerade versucht haben, die Methode mit der Wrapper-Klasse zu finden, ohne sie aufzurufen. Ich beschloss, dafür zu sorgen, und es hat funktioniert. Ich fühle mich jetzt ziemlich dumm. Vielen Dank. – Apropos

0

Das unmittelbare Problem in Ihrem Code ist, dass obj ein Objekt ist und daher keine Instanz eines primitiven Typs sein kann. (Es muss eine Instanz des entsprechenden Wrappertyps sein). Der Aufruf primClass.cast(obj) muss für jede primitive Typklasse fehlschlagen.

Wenn Sie jedoch einfach eine primitive Wrapper-Instanz in einen String umwandeln möchten, rufen Sie einfach die toString()-Methode der Instanz auf.

+0

Das Problem dabei ist, dass die Methode toString den primitiven Typ als Argument akzeptiert - nicht den Wrapper. Ich habe versucht, es als den Wrappertyp zu werfen und es auf diese Weise zu übergeben, aber es löst eine Ausnahme über Argumenttyp-Nichtübereinstimmung aus. Wenn Sie versuchen, getMethod als toString mit einem Wrapper-Typ als Argument zu erhalten, wird erwartungsgemäß eine NoSuchMethodException ausgelöst. – Apropos

0

Vielleicht ist etwas, was ich nicht verstehe in Ihrer Frage, aber für primitive, können Sie ""+primitive tun, um es in einen String zu werfen.

+0

Technisch ist dies nicht Casting, sondern Konvertierung. Es ist jedoch immer noch einfach. –

+0

Könntest du den Unterschied zwischen Casting und Conversion für Primitive in Java erklären? – Istao

0

Was Sie zu tun versuchen, ergibt keinen wirklichen Sinn .... wenn Ihre Funktion mit einem primitiven Argument (z. B. einem int) aufgerufen wird, wird sie automatisch in eine Ganzzahl eingerahmt. So könnte man genauso gut einfach anrufen obj.toString() auf sie .....

Allerdings, wenn Sie wirklich etwas Besonderes mit Primitiven tun wollen, möchten Sie vielleicht so etwas wie die folgenden mit der Methode Überlastung tun:

private String toString(Object obj){ 
    return obj.toString(); 
} 

private String toString(int intValue) { 
    // code to return string for the primitive int case, assuming it is different 
} 

// more overloads for other primitive argument types as needed..... 

Dies kann in einigen Fällen eine sehr nützliche Technik für den Umgang mit Primitiven sein.

+0

obj.toString() funktioniert nicht (primitive Typen können nicht dereferenziert werden). Das ist der ganze Grund, warum ich dieses Problem hatte. Ich müsste wissen, welcher Wrapper es war und die toString() -Methode auf diese Weise aufrufen, was ich gerade versuchte. – Apropos

0

String.valueOf(arg) wird es auch schön tun.

+0

Das ist so viel einfacher. Während ich versuchte, ein interessantes Experiment zu machen (und die Tatsache, dass ich es nicht herausfinden konnte, war ärgerlich), das ist wirklich die Antwort, denke ich. Ich kann nicht glauben, dass dies bei den verschiedenen Suchen, die ich probiert habe, nie aufgetaucht ist. Vielen Dank. – Apropos

3

Vielleicht vermisse ich etwas, aber obj.toString() würde tun.

Wenn Sie sich die Implementierungen ansehen, ruft sie String.valueOf(value) an, die wiederum Double.toString(..) oder Long.toString(..) oder was auch immer ruft. Wenn Sie also toString() aufrufen, wird automatisch die erforderliche Methode aufgerufen. Ohne jede Reflexion von deinem Teil.