Beim Hinzufügen 'a' + 'b'
werden 195 ausgegeben. Ist der Ausgabedatentyp char
oder int
?
Beim Hinzufügen 'a' + 'b'
werden 195 ausgegeben. Ist der Ausgabedatentyp char
oder 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 += y
mit den kleineren Typen zu simulieren , verwendet der Compiler iadd
die 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 char
und 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 66
den 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 temp
akzeptiert automatisch den c
Typ char und erzeugt temp=A
auf 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 c
es 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
char
ist 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.
char
als 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 int
beim Hinzufügen von zwei char
s 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
int
und Integer
sind nicht dasselbe. Eine überzeugendere Überprüfung besteht darin, zu versuchen, a + b
einer int
Variablen oder einer char
Variablen zuzuweisen . Letzteres gibt einen Übersetzungsfehler , die in der Tat sagt : „Sie können nicht zuordnen int
zu einem char
“.
char
wird als Unicode
Werte dargestellt und wobei Unicode-Werte \u
gefolgt von Hexadecimal
Werten dargestellt werden.
Wie jede arithmetische Operation für char
Werte, auf die heraufgestuft wird, int
wird das Ergebnis von 'a' + 'b'
als berechnet
1.) Wenden Sie die Unicode
Werte auf die entsprechende char
Verwendung anUnicode Table
2.) Wenden Sie die Hexadezimal-Dezimal- Konvertierung an und führen Sie dann die Operation für Decimal
Werte 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 int
a 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 int
Ausdrucksergebnisses auf a zulässt char
.
Im zweiten Beispiel y
handelt 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 int
nicht 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 y
als zu deklarieren final
.)
char
der Wert von'a' + 'b'
nicht195
aber'Ã'