При добавлении 'a' + 'b'
он производит 195. Является ли выходной тип данных char
или int
?
В Java это результат добавления двух символов int или char?
Ответ 1
Результатом добавления Java-символов, шорт или байтов является int:
Спецификация языка Java в двоичном цифровом продвижении:
- Если какой-либо из операндов имеет ссылочный тип, преобразование распаковки (П. 5.1.8). Тогда:
- Если оба операнда имеют тип double, другой преобразуется в double.
- В противном случае, если один из операндов имеет тип float, другой преобразуется в float.
- В противном случае, если либо операнд имеет тип long, другой - длинный.
- В противном случае оба операнды преобразуются в тип int.
Но обратите внимание на то, что он говорит о сложных операторах присваивания (например, + =):
Результат двоичной операции преобразуется в тип левой переменной... и результат преобразования сохраняется в переменной.
Например:
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
Один из способов узнать тип результата, в общем, заключается в том, чтобы передать его объекту и спросить его, какой класс он:
System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer
Если вы заинтересованы в производительности, обратите внимание, что байт-код Java даже не имеет специальных инструкций для арифметики с меньшими типами данных. Например, для добавления есть команды iadd
(для ints), ladd
(для longs), fadd
(для поплавков), dadd
(для парных) и что это. Чтобы имитировать x += y
с меньшими типами, компилятор будет использовать iadd
, а затем обнулить верхние байты int, используя команду типа i2c
( "int to char" ). Если у родного процессора есть выделенные инструкции для 1-байтовых или 2-байтовых данных, до виртуальной машины Java для оптимизации во время выполнения.
Если вы хотите объединить символы как строку, а не интерпретировать их как числовой тип, существует множество способов сделать это. Самым простым является добавление пустой строки в выражение, поскольку добавление char и строки приводит к String. Все эти выражения приводят к String "ab"
:
-
'a' + "" + 'b'
-
"" + 'a' + 'b'
(это работает, потому что сначала оценивается"" + 'a'
, если""
находилось в конце, вы получали бы"195"
) -
new String(new char[] { 'a', 'b' })
-
new StringBuilder().append('a').append('b').toString()
-
String.format("%c%c", 'a', 'b')
Ответ 2
Двоичные арифметические операции на char
и byte
(и short
) продвигаются к int
- JLS 5.6.2.
Ответ 3
Вы можете изучить следующие выражения о char
.
char c='A';
int i=c+1;
System.out.println("i = "+i);
Это совершенно справедливо в Java и возвращает 66
, соответствующее значение символа (Unicode) c+1
.
String temp="";
temp+=c;
System.out.println("temp = "+temp);
Это слишком актуально в Java, а переменная типа String temp
автоматически принимает c
типа char и производит temp=A
на консоли.
Все следующие утверждения также действительны в 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);
Хотя c
является типом char
, он может быть предоставлен без ошибок в соответствующих конструкторах, и все приведенные выше утверждения рассматриваются как действительные. Они производят следующие выходы соответственно.
intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65
char
является примитивным числовым интегральным типом и, как таковой, подчиняется всем правилам этих зверей, включая преобразования и продвижение по службе. Вы хотите прочитать об этом, и JLS является одним из лучших источников для этого: "Конверсии и рекламные акции" . В частности, прочитайте короткий бит на "5.1.2 Расширение примитивного преобразования".
Ответ 4
Компилятор Java может интерпретировать его как один.
Проверьте это, написав программу и ищите ошибки компилятора:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
Если это a char, тогда первая строка даст мне ошибку, а вторая - нет. Если это int, тогда произойдет обратное.
Я скомпилировал его, и я получил..... НЕТ ОШИБКИ. Так что Java принимает оба.
Однако, когда я их распечатал, я получил:
int: 195
char: Ã
Что происходит, когда вы делаете:
char result2 = 'a' + 'b'
выполняется неявное преобразование ( "примитивное сужение преобразования" от int до char).
Ответ 5
В соответствии с бинарными правилами продвижения, если ни один из операндов не является double, float или long, оба передаются в int. Тем не менее, я настоятельно рекомендую против типа char как числового, такого рода поражения его цели.
Ответ 6
Пока у вас уже есть правильный ответ (ссылка на JLS), здесь немного кода, чтобы убедиться, что вы получаете int
при добавлении двух char
s.
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());
}
}
Выходной сигнал
java.lang.Integer
Ответ 7
char
представлен как Unicode
и где значения Unicode представлены \u
, за которыми следуют Hexadecimal
значения.
Как любая арифметическая операция над значениями char
повышена до int
, поэтому результат 'a' + 'b'
вычисляется как
1.) Примените значения Unicode
к соответствующему char
, используя Unicode Table
2.) Примените шестнадцатеричное к десятичному преобразованию и затем выполните операцию над значениями Decimal
.
char Unicode Decimal
a 0061 97
b 0062 98 +
195
Пример
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
Следовательно, 97 + 98 = 195
Пример 2
char Unicode Decimal
Ջ 054b 1355
À 00c0 192
--------
1547 +
1163 -
7 /
260160 *
11 %
Ответ 8
Здесь что-то странное. Следующие компиляции:
char x;
x = 'a' + 'b';
Но это не так:
char x;
x = 'a';
x = x + 'b';
Похоже, что оба выражения ('a' + 'b' и x + 'b') приводят к целым числам следующим тестом:
Object obj = 'a'+'b';
System.out.println(obj.getClass().getName());
char x = 'a';
Object obj2 = x+'b';
System.out.println(obj2.getClass().getName());
Так почему бы второй случай не скомпилировать? Кстати, вы можете исправить это, выставив все выражение как char:
x = (char)(x+'b');
Это похоже на несогласованность в семантике Java - любое выражение char должно быть взаимозаменяемым с другим в любом контексте. Кто-нибудь знает способ понять это?