При добавлении 'a' + 'b'
получается 195. Тип выходных данных char
или int
?
В Java результатом добавления двух символов является int или char?
Ответы (8)
Результатом добавления символов Java, шорт или байтов является int:
Спецификация языка Java для преобразования двоичных чисел:
- Если какой-либо из операндов имеет ссылочный тип, выполняется преобразование распаковки (§5.1.8). Потом:
- Если один из операндов имеет тип double, другой преобразуется в double.
- В противном случае, если один из операндов имеет тип float, другой преобразуется в float.
- В противном случае, если один из операндов имеет тип long, другой преобразуется в 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
(для целых чисел), ladd
(для длинных чисел), fadd
(для чисел с плавающей запятой), dadd
(для двойных чисел) и все. Чтобы имитировать x += y
с меньшими типами, компилятор будет использовать iadd
, а затем обнулять старшие байты int с помощью инструкции типа i2c
("int to char"). Если собственный ЦП имеет специальные инструкции для 1-байтовых или 2-байтовых данных, виртуальная машина Java должна оптимизировать их во время выполнения.
Если вы хотите объединить символы как строку, а не интерпретировать их как числовой тип, есть много способов сделать это. Проще всего добавить в выражение пустую строку, потому что добавление char и строки приводит к строке. Результатом всех этих выражений является строка "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')
Двоичные арифметические операции над char
и byte
(и short
) преобразуются в int
-- JLS 5.6.2.
Вы можете выучить следующие выражения о 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 Расширение примитивного преобразования».
Компилятор Java может интерпретировать его как любой из них.
Проверьте это, написав программу и поискав ошибки компилятора:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
Если это символ, то первая строка выдаст мне ошибку, а вторая нет. Если это int, то произойдет обратное.
Я скомпилировал его и получил... НЕТ ОШИБОК. Значит, Java поддерживает и то, и другое.
Однако, когда я их напечатал, я получил:
интервал: 195
символ: Ã
Что происходит, когда вы делаете:
char result2 = 'a' + 'b'
выполняется неявное преобразование (примитивное сужающее преобразование из int в char).
z + y
не является постоянным выражением. Смотрите мой ответ для более подробного объяснения... со ссылками JLS.
- person Stephen C; 24.05.2020
В соответствии с правилами продвижения двоичных файлов, если ни операндов является двойным, плавающим или длинным, оба повышаются до int. Тем не менее, я настоятельно рекомендую не рассматривать тип char как числовой, так как это противоречит его назначению.
char
в качестве числового значения полностью соответствует его назначению, поэтому JLS уделяет такому использованию так много слов.
- person Lew Bloch; 07.01.2017
Хотя у вас уже есть правильный ответ (упоминаемый в JLS), вот небольшой код, чтобы убедиться, что вы получаете int
при добавлении двух char
.
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
int
и Integer
— это не одно и то же. Более убедительная проверка — попытаться присвоить a + b
переменной int
или переменной char
. Последний выдает ошибку компиляции, которая говорит о том, что вы не можете присвоить int
char
.
- person Stephen C; 24.05.2020
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*163) + (0*162) + (6*161) + (1*160 )
(0*4096) + (0*256) + (6*16) + (1*1)
0 + 0 + 96 + 1 = 97
0062
(0*163) + (0*162) + (6*161) + (2*160 )
(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 %
Хотя ответ Боанна правильный, существует сложность, которая применяется к случаю константных выражений, когда они появляются в контекстах назначения.
Рассмотрим следующие примеры:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
Что здесь происходит? Они имеют в виду одно и то же, не так ли? И почему законно присваивать int
char
в первом примере?
Когда постоянное выражение появляется в контексте присваивания, компилятор Java вычисляет значение выражения и проверяет, находится ли оно в диапазоне типа, которому вы присваиваете значение. Если это так, то применяется неявное сужающее примитивное преобразование.
В первом примере
'a' + 'b'
является константным выражением, и его значение уместится вchar
, поэтому компилятор допускает неявное сужение результата выраженияint
доchar
.Во втором примере
y
является переменной, поэтомуy + 'b'
НЕ является постоянным выражением. Таким образом, несмотря на то, что Blind Freddy может видеть, что значение подходит, компилятор НЕ допускает каких-либо неявных сужается, и вы получаете ошибку компиляции, говорящую о том, чтоint
не может быть присвоеноchar
.
Есть и другие предостережения относительно того, когда в этом контексте разрешено неявное сужающее примитивное преобразование; см. JLS 5.2 и JLS 15.28 для Полная информация.
Последний подробно объясняет требования к константному выражению. Это может быть не то, что вы думаете. (Например, простое объявление y
как final
не поможет.)
char
, то значение'a' + 'b'
было бы не195
, а'Ã'
. - person Joren   schedule 01.01.2012