Beim Hinzufügen 'a' + 'b'werden 195 ausgegeben. Ist der Ausgabedatentyp charoder int?
Beim Hinzufügen 'a' + 'b'werden 195 ausgegeben. Ist der Ausgabedatentyp charoder int?
Antworten:
Das Ergebnis des Hinzufügens von Java-Zeichen, Kurzschlüssen oder Bytes ist ein int :
Java-Sprachspezifikation zur binären numerischen Förderung :
- Wenn einer der Operanden vom Referenztyp ist, wird die Unboxing-Konvertierung (§5.1.8) durchgeführt. Dann:
- Wenn einer der Operanden vom Typ double ist, wird der andere in double konvertiert.
- Wenn einer der Operanden vom Typ float ist, wird der andere in float konvertiert.
- Wenn einer der Operanden vom Typ long ist, wird der andere in long konvertiert.
- Andernfalls werden beide Operanden in den Typ int konvertiert.
Beachten Sie jedoch, was es über zusammengesetzte Zuweisungsoperatoren sagt (wie + =) :
Das Ergebnis der Binäroperation wird in den Typ der linken Variablen konvertiert ... und das Ergebnis der Konvertierung wird in der Variablen gespeichert.
Zum Beispiel:
char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK
Eine Möglichkeit, den Typ des Ergebnisses im Allgemeinen herauszufinden, besteht darin, es in ein Objekt umzuwandeln und zu fragen, um welche Klasse es sich handelt:
System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer
Wenn Sie an Leistung interessiert sind, beachten Sie, dass der Java-Bytecode nicht einmal spezielle Anweisungen für die Arithmetik mit den kleineren Datentypen enthält. Zum Hinzufügen gibt es zum Beispiel Anweisungen iadd(für Ints), ladd(für Longs), fadd(für Floats), dadd(für Doubles), und das war's. Um x += ymit den kleineren Typen zu simulieren , verwendet der Compiler iadddie oberen Bytes des int und setzt sie dann mit einer Anweisung wie i2c("int to char") auf Null . Wenn die native CPU über dedizierte Anweisungen für 1-Byte- oder 2-Byte-Daten verfügt, muss die virtuelle Java-Maschine dies zur Laufzeit optimieren.
Wenn Sie Zeichen als Zeichenfolge verketten möchten, anstatt sie als numerischen Typ zu interpretieren, gibt es viele Möglichkeiten, dies zu tun. Am einfachsten ist es, dem Ausdruck einen leeren String hinzuzufügen, da das Hinzufügen eines Zeichens und eines Strings zu einem String führt. Alle diese Ausdrücke führen zum String "ab":
'a' + "" + 'b'"" + 'a' + 'b'(Dies funktioniert, weil "" + 'a'zuerst ausgewertet wird; wenn die ""am Ende stattdessen wären, würden Sie bekommen "195")new String(new char[] { 'a', 'b' })new StringBuilder().append('a').append('b').toString()String.format("%c%c", 'a', 'b')Binäre arithmetische Operationen an charund byte(und short) fördern zu int- JLS 5.6.2.
Möglicherweise möchten Sie die folgenden Ausdrücke über lernen char.
char c='A';
int i=c+1;
System.out.println("i = "+i);
Dies ist in Java vollkommen gültig und gibt 66den entsprechenden Wert des Zeichens (Unicode) von zurück c+1.
String temp="";
temp+=c;
System.out.println("temp = "+temp);
Dies ist in Java zu gültig und die Variable vom Typ String tempakzeptiert automatisch den cTyp char und erzeugt temp=Aauf der Konsole.
Alle folgenden Aussagen gelten auch in Java!
Integer intType=new Integer(c);
System.out.println("intType = "+intType);
Double doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);
Float floatType=new Float(c);
System.out.println("floatType = "+floatType);
BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);
Long longType=new Long(c);
System.out.println("longType = "+longType);
Obwohl ces sich um eine Art von handelt char, kann es in den jeweiligen Konstruktoren fehlerfrei angegeben werden, und alle obigen Anweisungen werden als gültige Anweisungen behandelt. Sie erzeugen jeweils die folgenden Ausgaben.
intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65
charist ein primitiver numerischer Integraltyp und unterliegt als solcher allen Regeln dieser Bestien, einschließlich Umbauten und Beförderungen. Sie sollten sich darüber informieren, und das JLS ist eine der besten Quellen dafür: Conversions und Promotions . Lesen Sie insbesondere das kurze Bit zu "5.1.2 Erweitern der primitiven Konvertierung".
Der Java-Compiler kann es als eines von beiden interpretieren.
Überprüfen Sie dies, indem Sie ein Programm schreiben und nach Compilerfehlern suchen:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
Wenn es ein Zeichen ist, gibt mir die erste Zeile einen Fehler und die zweite nicht. Wenn es ein int ist, wird das Gegenteil passieren.
Ich habe es zusammengestellt und ich habe ... KEINE FEHLER. Java akzeptiert also beides.
Als ich sie jedoch druckte, bekam ich:
int: 195
char: Ã
Was passiert ist, wenn Sie Folgendes tun:
char result2 = 'a' + 'b'
Es wird eine implizite Konvertierung durchgeführt (eine "primitive Verengungskonvertierung" von int nach char ).
Gemäß den binären Heraufstufungsregeln werden beide zu int heraufgestuft, wenn keiner der Operanden double, float oder long ist. Ich rate jedoch dringend davon ab, den Zeichentyp als numerisch zu behandeln, da dies seinen Zweck zunichte macht.
charals numerischer Wert liegt vollständig in seinem Zweck, weshalb das JLS einer solchen Verwendung so viel Wortschatz widmet.
Während Sie bereits die richtige Antwort haben (auf die im JLS verwiesen wird), finden Sie hier einen Code, mit dem Sie überprüfen können, ob Sie intbeim Hinzufügen von zwei chars eine erhalten.
public class CharAdditionTest
{
public static void main(String args[])
{
char a = 'a';
char b = 'b';
Object obj = a + b;
System.out.println(obj.getClass().getName());
}
}
Die Ausgabe ist
java.lang.Integer
intund Integersind nicht dasselbe. Eine überzeugendere Überprüfung besteht darin, zu versuchen, a + beiner intVariablen oder einer charVariablen zuzuweisen . Letzteres gibt einen Übersetzungsfehler , die in der Tat sagt : „Sie können nicht zuordnen intzu einem char“.
charwird als UnicodeWerte dargestellt und wobei Unicode-Werte \ugefolgt von HexadecimalWerten dargestellt werden.
Wie jede arithmetische Operation für charWerte, auf die heraufgestuft wird, intwird das Ergebnis von 'a' + 'b'als berechnet
1.) Wenden Sie die UnicodeWerte auf die entsprechende charVerwendung anUnicode Table
2.) Wenden Sie die Hexadezimal-Dezimal- Konvertierung an und führen Sie dann die Operation für DecimalWerte aus.
char Unicode Decimal
a 0061 97
b 0062 98 +
195
Beispiel
0061
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (1 * 16 0 )
(0 * 4096) + (0 * 256) + (6 * 16) + (1 * 1)
0 + 0 + 96 + 1 = 97
0062
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (2 * 16 0 )
(0 * 4096) + (0 * 256) + (6 * 16) + (2 * 1)
0 + 0 + 96 + 2 = 98
Daher 97 + 98 = 195
Beispiel 2
char Unicode Decimal
Ջ 054b 1355
À 00c0 192
--------
1547 +
1163 -
7 /
260160 *
11 %
Während Boanns Antwort richtig ist, gibt es eine Komplikation, die für den Fall konstanter Ausdrücke gilt, wenn sie in Zuweisungskontexten erscheinen .
Betrachten Sie die folgenden Beispiele:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
Was ist los? Sie bedeuten dasselbe, nicht wahr? Und warum ist es legal, im ersten Beispiel ein inta zuzuweisen char?
Wenn ein konstanter Ausdruck in einem Zuweisungskontext angezeigt wird, berechnet der Java-Compiler den Wert des Ausdrucks und prüft, ob er im Bereich des Typs liegt, dem Sie zuweisen. Wenn dies der Fall ist, wird eine implizite Verengung der primitiven Konvertierung angewendet.
Im ersten Beispiel 'a' + 'b'handelt es sich um einen konstanten Ausdruck, dessen Wert in a passt char, sodass der Compiler die implizite Eingrenzung des intAusdrucksergebnisses auf a zulässt char.
Im zweiten Beispiel yhandelt es sich um eine Variable, also y + 'b'NICHT um einen konstanten Ausdruck. Obwohl Blind Freddy sehen kann, dass der Wert passt, lässt der Compiler KEINE implizite Verengung zu, und Sie erhalten einen Kompilierungsfehler, der besagt, dass a intnicht zugewiesen werden kann char.
Es gibt einige andere Vorbehalte, wenn in diesem Zusammenhang eine implizite Verengung der primitiven Konvertierung zulässig ist. Ausführliche Informationen finden Sie in JLS 5.2 und JLS 15.28 .
Letzteres erklärt ausführlich die Anforderungen an einen konstanten Ausdruck . Es kann nicht sein, was Sie vielleicht denken. (Zum Beispiel hilft es nicht , nur yals zu deklarieren final.)
charder Wert von'a' + 'b'nicht195aber'Ã'