Ошибка компиляции: приведение - PullRequest
2 голосов
/ 03 мая 2010

Может кто-нибудь объяснить мне, почему следующий фрагмент кода не компилируется. Ошибка: «Possible loss of precision.»:

byte a = 50;
byte b = 40;
byte sum = (byte)a + b;
System.out.println(sum);

Спасибо.

Ответы [ 4 ]

4 голосов
/ 03 мая 2010

Обратите внимание, что приведение имеет более высокий приоритет, чем оператор +. Ваш код делает это:

byte a = 50;
byte b = 40;
byte sum = ((byte)a) + b;
System.out.println(sum);

Приведение избыточно, поскольку a уже является byte. Вы, вероятно, имели в виду это:

byte a = 50;
byte b = 40;
byte sum = (byte) (a + b);
System.out.println(sum);
3 голосов
/ 03 мая 2010

Поскольку две байтовые переменные являются операндами +, они неявно переводятся в int. Это называется Числовое продвижение. Поскольку int больше байта, а результат a + b приводит к int, приведение к байту может отрезать некоторые биты, так как int больше байта. Отсюда и «потеря точности»

Документ для неявного числового продвижения:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983

Док по размерам типов:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html

1 голос
/ 03 мая 2010

Вы правильно сделали, указав, что приведение требуется, но, к сожалению, вы не применили его к правильному выражению из-за приоритета операторов.

Рассмотрим следующий фрагмент:

static void f(char ch) {
    System.out.println("f(char)");
}
static void f(int i) {
    System.out.println("f(int)");
}
public static void main(String[] args) {
    char ch = 'X';
    f( (char)  ch + 1  ); // prints "f(int)"
    f( (char) (ch + 1) ); // prints "f(char)"
}

Приведение имеет более высокий приоритет, чем дополнение, поэтому фрагмент напечатает, что он делает. То есть первый вызов эквивалентен f( ((char) ch) + 1 );. Результатом добавления является int, поэтому вызывается перегрузка f(int).

Урок здесь заключается в том, что вы должны всегда использовать круглые скобки , если вы не делаете очень простое приведение. В общем, всегда рассматривайте возможность использования скобок, чтобы сделать порядок вычисления явным, даже если в этом нет необходимости. Они приводят к лучшему, более читаемому коду.

1 голос
/ 03 мая 2010

Байты добавляются с использованием арифметики "int"; таким образом, результатом является int и его необходимо преобразовать из int в байт, что приводит к возможности усечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...