2017-01-05 1 views
4

Um einige Bytecode-Analyse zu vereinfachen, möchte ich explizite (nach unten) Umwandlungen von primitiven Typen in einem Java-Programm durch Aufrufe der entsprechenden Methode des Boxed-Typs ersetzen. In den meisten Fällen ist es einfach:Gibt es eine Methode in Java, die den Cast des primitiven Typs zu Character nachahmt?

double d = 42.0; 
int i = (int)d; 

Für alle signierten Typen Dies funktioniert in

Double tmp = new Double(d); 
int i = tmp.intValue(); 

gedreht werden. Aber es gibt keine solchen Methoden für char und Character. Das heißt, Integer, Float usw. haben die Methoden intValue, floatValue usw., aber keine hat eine Methode charValue. Gibt es eine jdk-Methode, um vom primitiven Typ zum char/Character zu gelangen?

Also im Grunde ist es so etwas wie folgt aus:

Integer num = new Integer(65); 
char ch = num.charValue(); 

Und der Schlüssel ist nicht (char) zu verwenden.

+0

http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#charValue()? –

+0

@ScaryWombat Ich denke, OP will es auf 'java.lang.Integer' usw. – dasblinkenlight

+1

Nein ist es nicht so weit wie ich Ihre Frage –

Antwort

3

Wenn Sie Bytecode ändern, müssen Sie nicht zu char umwandeln. Im Bytecode ist der Typ char ein Bürger zweiter Klasse, der tatsächlich als int behandelt wird. Von JVMS §4.9.2:

Ein Befehl auf Werten vom Typ Betrieb int wird auch auf Werten vom Typ boolean, byte, char und short zu betreiben erlaubt.

Wie in §2.3.4 und §2.11.1 erwähnt, wandelt die Java Virtual Machine intern Werte von Typen boolean, byte, short und charint eingeben.)

So, während Sie können‘ t, sagen Sie, eine int zu einer char in der Sprache Java ohne eine explizite Cast zuweisen, können Sie dies in der Bytecode, da sie die gleiche "verification type", die int ist. Die Bytecode-Darstellung einer char ist nur eine int, die zufällig ihre oberen zwei Bytes Null hat. Also statt:

char ch = num.charValue(); 

würden Sie in der Lage sein, um wegzukommen mit (in Bytecode):

int ch = num.intValue() & 0x0000FFFF; 

Und dann so tun, als nur, dass ch ist ein char (zB übergibt es an Methoden, die eine erwarten char oder speichern Sie es in einem char Feld oder Array).

Allerdings, wenn ich es richtig verstanden habe, ist das, was die i2cint zu char Guss Anweisung bereits der Fall ist, so ist es durch eine explizite ersetzen UND-Operation wird nicht einfacher sein wird.

Es ist auch überraschend schwer zu finden, was tatsächlich passiert, wenn Sie ein (signiertes) Double in ein (unsigned) Zeichen umwandeln.

Wenn Sie werfen aus float oder double-byte, short oder char, es wirft zunächst int, die out-of-Range-Werte Integer.MAX_VALUE oder Integer.MIN_VALUE sättigt und kürzt dann die Bytes des int zu passen der letzte Typ. Siehe JLS §5.1.3 – Narrowing Primitive Conversion. Der Abschneideschritt bedeutet, dass die Umwandlung von Out-of-range Gleitkommawerte zu byte, short oder char ist wahrscheinlich nicht ein brauchbares Ergebnis geht zu geben.

+0

Wow! Dafür ist StackOverflow gemacht! Tolle Antwort und vielen Dank. –

+0

FWIW, nur um zu erklären, warum ich nicht i2c verwendet habe: meine Analyse ist eigentlich auf dieser jimple Zwischendarstellung des Bytecode (siehe https://sable.github.io/soot/) und das Wieder fügt die explizite Umwandlung zu Reduziere die Gesamtzahl der Anweisungen, die du handhaben musst. –

1

Ich glaube nicht, dass es eine direkte Methode in den Klassen gibt, um eine char Darstellung zu erhalten. Die einfache Lösung ist jedoch:

Integer num = new Integer(65); 
char ch = (char)num.intValue(); 

Ich bin sicher, dass Sie daran gedacht haben. Aber es scheint keinen besseren Weg zu geben.

+0

, dass die Frage nicht helfen ... ist, kann ich ein Programm schreiben, das nicht den '(char) hat ...' Teil ... –

+0

Ich glaube nicht, dass es eine direkte Methode gibt. Sie können das Javadoc überprüfen. Da es nicht da ist, kannst du nicht bekommen, wonach du verlangst. Was ist das Problem bei der Eingabe des int in char? Immerhin ist der Byte-Code derselbe. – Shakhar

+0

@ MartinSchäf: Nein. Das geht nicht. –

Verwandte Themen