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()
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.
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".
Ich bin überrascht, dass Sie im zweiten Fall keine Compiler-Warnung über einen möglichen Genauigkeitsverlust aufgrund einer Verengung erhalten haben.
Hot Licks
@eboix: Sie haben geschrieben "Der Compiler wandelt automatisch entweder in char oder int um" [sic] ... Was nicht korrekt ist, weil ein int nicht in ein int "umgewandelt" wird und der Übergang von einem int zu einem char nicht aufgerufen wird eine "Besetzung", aber eine "sich verengende primitive Bekehrung"; )
TacticalCoder
Ja. Das habe ich auch erwartet. Ich hatte tatsächlich einen Teil meiner Antwort darüber geschrieben, bevor ich mein Programm erstellt habe, aber dann habe ich es gelöscht, als ich sah, dass ich keine Warnungen oder Fehler bekam.
Eboix
@eboix: eh eh :) Ich hätte es bearbeitet, aber ich habe noch keine 2 000 Reputationspunkte, daher mein Kommentar anstelle einer Bearbeitung; )
TacticalCoder
Wenn Sie möchten, @ user988052, kann ich es wieder in das ändern, was es war, und Sie können es bearbeiten, um Punkte zu erhalten. Sie können es weiterhin bearbeiten, wenn Sie weniger als 2000 Reputationspunkte haben. Das einzige ist, dass die Person, die den Beitrag verfasst hat, die Bearbeitung akzeptieren muss. Ich werde es jetzt wieder ändern, damit Sie die zwei Punkte erhalten, die Ihnen zu Recht gehören.
eboix
1
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.
Die Verwendung charals numerischer Wert liegt vollständig in seinem Zweck, weshalb das JLS einer solchen Verwendung so viel Wortschatz widmet.
Lew Bloch
1
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.
publicclassCharAdditionTest{
publicstaticvoidmain(String args[]){
char a = 'a';
char b = 'b';
Object obj = a + b;
System.out.println(obj.getClass().getName());
}
}
Dies ist keine überzeugende Bestätigung, da Sie eine Box-Konvertierung in die Mischung geworfen haben. Die Typen 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“.
Stephen C
0
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.
Zu Ihrer Information, meine detaillierte Antwort auf den obigen Kommentar wurde von Mods entfernt, die den Grund für die Migration meiner Antwort von einem gelöschten Beitrag erklärten. Wenn meine Antwort gelöscht wurde, um die Fehler der SO-Moderation zu vertuschen, können Sie dann zumindest den obigen Kommentar entfernen oder das Publikum irgendwie angeben, damit ich keinen weiteren Kommentar schreiben muss? Fragen an SO Mods
Pavneet_Singh
Ich stehe zu meinem Kommentar. Wie ich Ihnen geantwortet habe ... aber dann gelöscht habe ... ändert der Grund, warum Sie diese Frage hier gepostet haben, nichts an der Tatsache, dass sie zu 95% vom Thema abweicht und 5% frühere Antworten wiederholt. Wenn Sie die Ergebnisse Ihrer verschwendeten Arbeit speichern möchten, ist es besser, sie auf Ihrer Festplatte zu speichern. Oder finden Sie eine andere Frage, für die es relevant ist.
Stephen C
Wenn Sie Probleme mit den Moderatoren haben, nehmen Sie diese in meta.stackoverflow.com auf. Und Beweise vorlegen. Alles, was ich hier versuche, ist >> diese << Fragen und Antworten aufzuräumen.
Stephen C
Ich verstehe Ihre Ansicht, kann aber nicht verstehen, dass die Details der Unicode-Konvertierung anhand von Beispielen ignoriert werden. Dies ist ein zusätzlicher Wert, der einigen Lesern helfen könnte. Daher möchte ich diese Antwort behalten (ich verstehe, dass sie für Sie nicht nützlich ist und falsch erscheint). Thema). Ich vermeide Meta und ähnliche Orte, da es nicht einfach ist, solche Dinge ohne Kraft oder Unterstützung zu tun, was viel Zeit und Mühe kostet. Ich ziehe es vor, meinen inneren Frieden zu bewahren.
Pavneet_Singh
0
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'; // OKchar 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.)
char
der Wert von'a' + 'b'
nicht195
aber'Ã'
Antworten:
Das Ergebnis des Hinzufügens von Java-Zeichen, Kurzschlüssen oder Bytes ist ein int :
Java-Sprachspezifikation zur binären numerischen Förderung :
Beachten Sie jedoch, was es über zusammengesetzte Zuweisungsoperatoren sagt (wie + =) :
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. Umx += y
mit den kleineren Typen zu simulieren , verwendet der Compileriadd
die oberen Bytes des int und setzt sie dann mit einer Anweisung wiei2c
("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')
quelle
Binäre arithmetische Operationen an
char
undbyte
(undshort
) fördern zuint
- JLS 5.6.2.quelle
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ückc+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 denc
Typ char und erzeugttemp=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 handeltchar
, 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".quelle
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:
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 ).
quelle
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.
quelle
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 zweichar
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
quelle
int
undInteger
sind nicht dasselbe. Eine überzeugendere Überprüfung besteht darin, zu versuchen,a + b
einerint
Variablen oder einerchar
Variablen zuzuweisen . Letzteres gibt einen Übersetzungsfehler , die in der Tat sagt : „Sie können nicht zuordnenint
zu einemchar
“.char
wird alsUnicode
Werte dargestellt und wobei Unicode-Werte\u
gefolgt vonHexadecimal
Werten dargestellt werden.Wie jede arithmetische Operation für
char
Werte, auf die heraufgestuft wird,int
wird das Ergebnis von'a' + 'b'
als berechnet1.) Wenden Sie die
Unicode
Werte auf die entsprechendechar
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
Unicode To Decimal Converter
Beispiel
0061
0062
Daher
97 + 98 = 195
Beispiel 2
char Unicode Decimal Ջ 054b 1355 À 00c0 192 -------- 1547 + 1163 - 7 / 260160 * 11 %
quelle
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 zuzuweisenchar
?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 passtchar
, sodass der Compiler die implizite Eingrenzung desint
Ausdrucksergebnisses auf a zulässtchar
.Im zweiten Beispiel
y
handelt es sich um eine Variable, alsoy + '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 aint
nicht zugewiesen werden kannchar
.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 deklarierenfinal
.)quelle