В Java результат добавления двух символов типа int или char? - PullRequest
68 голосов
/ 31 декабря 2011

При добавлении 'a' + 'b' получается 195. Выходной тип данных char или int?

Ответы [ 8 ]

119 голосов
/ 31 декабря 2011

Результатом добавления символов, шортов или байтов Java будет int :

Спецификация языка Java для двоичного числового продвижения :

  • Если какой-либо из операндов относится к ссылочному типу, преобразование без распаковки (§5.1.8) выполняется. Тогда:
  • Если любой из операндов имеет тип 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, чтобы оптимизировать ее во время выполнения.

Если вы хотите объединить символы в виде строки, а не интерпретировать их как числовой тип, существует множество способов сделать это. Самым простым является добавление пустой строки в выражение, потому что добавление символа и строки приводит к строке. Все эти выражения приводят к строке "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')
20 голосов
/ 31 декабря 2011

Двоичные арифметические операции над char и byteshort) повышаются до int - JLS 5.6.2.

7 голосов
/ 31 декабря 2011

Вы можете узнать следующие выражения о 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 Расширение примитивного преобразования».

3 голосов
/ 31 декабря 2011

Компилятор Java может интерпретировать его как один.

Проверьте это, написав программу и посмотрев ошибки компилятора:

public static void main(String[] args) {
    int result1 = 'a' + 'b';
    char result2 = 'a' + 'b';
}

Если это символ, то первая строка будетдай мне ошибку, а второй не будет.Если это int, то произойдет обратное.

Я скомпилировал его и получил ..... НЕТ ОШИБОК. Так что Java принимает оба.

Однако, когда я их напечатал, я получил:

int: 195

char: Ã

Что происходит, когда вы делаете:

char result2 = 'a' + 'b'

выполняется неявное преобразование («преобразование примитивного сужения» из int в char ).

2 голосов
/ 31 декабря 2011

Согласно бинарным правилам , если ни один из операндов не является двойным, плавающим или длинным, оба преобразуются в int.Тем не менее, я настоятельно рекомендую не относиться к типу char как к числовому, что побеждает его назначение.

1 голос
/ 03 февраля 2017

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

Unicode To Decimal Converter

Пример

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    %
1 голос
/ 31 декабря 2011

Несмотря на то, что у вас уже есть правильный ответ (на который есть ссылки в 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

0 голосов
/ 16 сентября 2014

Вот что-то странное.Следующие компиляции:

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 должно быть взаимозаменяемым с другим в любом контексте.Кто-нибудь знает способ понять это?

...