Есть только два типа целочисленных литералов, определенный в Java: int
и long
. Последний отличается от первого суффиксом L
или l
. (Литерал символов также является интегральным типом (может быть назначен, например, int
), но спецификация языка Java (JLS) обрабатывает его отдельно от целочисленных литералов.)
Помните, что (помимо определения параметров типового типа) , вид левой стороны присваивания не влияет на оценку правой части. Поэтому, если вы присваиваете что-то переменной типа long
, выражение будет оценено сначала, и только тогда результат будет преобразован в long
(если это возможно и необходимо).
Заявление
long a = 10;
вполне допустимо. Выражение правой стороны, состоящее только из целочисленного литерала 10
, будет оцениваться и затем продвигаться до long
, которое затем назначается переменной a
. Это хорошо работает, если вы не хотите присвоить значение, которое слишком велико, чтобы быть представленным в int
, и в этом случае вам нужно будет сделать литерал типа long
.
Эта «проблема» не ограничивается литералами. Рассмотрим следующее утверждение, что часто кусает новых пользователей:
long a = Integer.MAX_VALUE + 1;
Выражение в правой части оценивается с помощью int
арифметику и, следовательно, переполнении.Только тогда результат (− 2147483648) повышается до long
и присваивается a
, но уже слишком поздно. Если бы 1
был написан как 1L
, переполнение не произошло бы.
Почему мне не нужно это делать для short
или byte
?
Во-первых, обратите внимание, что литерал типа int
может содержать любое значение, которое вы могли бы назначить на short
или byte
поэтому описанная выше проблема не может произойти. Более того, это не так много, что вам «не нужно» использовать short
или byte
буквально, но что вы не можете, потому что такие литералы не определены. Это всегда беспокоило меня, потому что это означает, что нам часто приходится указывать byte
, если мы хотим вызвать функцию с литеральным аргументом.
Если вам нравится читать стандартное, вы можете найти главу о Integer Literals (§ 3.10.1) in the JLS.
Но зачем использовать длинный тип данных, если его обрабатывать как int? – Rhys
@ReeceLeu: переменная с левой стороны длинная. Но это не приводит к тому, что буквально на правой стороне тоже долго. Если да, то где остановиться? Должен ли 'long x =" 1234 ";' также работать? – Thilo
Все языки программирования фактически сталкиваются с одной и той же проблемой. Каждый определяет свое собственное правило относительно типа целочисленного литерала. Java в этом случае предпочитает выбирать int по умолчанию или долго, если он имеет суффикс L/l. Другие языки могут иметь целочисленное правило продвижения (например: int всегда вписывается в long, поэтому int literal может быть назначено длинной переменной путем продвижения своего типа в long) или просто обрабатывать каждый литерал как самый широкий целочисленный тип, который поддерживает компилятор. Это дизайнерское решение. – LeleDumbo