Неинициализированный int vs Integer
Я только учился на своей Java в рамках подготовки к экзамену, и у меня возникла проблема с неинициализированными значениями int/Integer.
class A
{
int x;
Integer y;
static int z;
static Integer z2;
public A(){}
}
Предположим, что я инициализирую объект класса A. A = new A();
Я пробовал это в компиляторе и получил результаты
a.x == 0; true
a.x == null; Static Error: Bad type in comparison expression
a.y == 0; java.lang.NullPointerException
a.y == null; true
a.z == 0; true
a.z == null; Static Error: Bad type in comparison expression
a.z2 == 0; NullPointerException
a.z2 == null; true
Кроме того, я попробовал еще несколько неинициализированных сравнений int/Interger в панели взаимодействий, чтобы узнать, получаю ли я разные результаты, если мои x, y не являются переменными экземпляра класса, поскольку они выше.
int x;
Integer y;
x == 0; true
x == null; Static Error: Bad type in comparison expression
y == 0; java.lang.NullPointerException
y == null; true
Однако мой профессор утверждает в лекции, что значения должны быть следующими:
x == 0; Uninitialized
x == null; Undefined
y == 0; java.lang.NullPointerException
y == null; Uninitialized
Теперь я не хочу сомневаться в том, кто пишет экзамен, но какие значения x == 0 и y == null истинны? Объяснение о том, почему было бы очень полезно, спасибо.
Ответы
Ответ 1
-
a.x == 0
- Истинно, потому что a.x имеет значение по умолчанию 0.
-
a.x == null
- Как отмечено, это ошибка времени компиляции. Это следует из §15.21.3: "Ошибка времени компиляции возникает, если невозможно преобразовать тип любого операнда в тип другой путем кастинговой конверсии (§5.5)". Тип null не преобразуется в число.
-
a.y == 0
- Это пытается удалить unbox a.y,
, который является null, поэтому он генерирует исключение NullPointerException. В отличие от вышеизложенного (который имеет буквальный нуль), компилятор не пытается выяснить во время компиляции, что a.y
будет null.
-
a.y == null
- Опять же, true, потому что a.y
инициализируется нулем
-
a.z == 0
- То же, что a.x
(кроме статического)
-
a.z == null
- То же, что a.x
(кроме статического)
-
a.z2 == 0
- То же, что a.y
(кроме статического)
-
a.z2 == null
- То же, что a.y
(кроме статического)
Проблема с областью взаимодействия заключается в том, что она до IDE, как ее реализовать. Если x и y являются локальными (неинициализированными) переменными, все четыре из ваших последних сравнений не скомпилируются.
Ответ 2
Значения Java простых типов, такие как int/long, не могут быть нулевыми, поэтому они инициализируются 0.
Ответ 3
В Java, переменные класса (статические), переменные экземпляра (те, что указаны в вашем примере), и компоненты массива заданы значениями по умолчанию. Локальные переменные, с другой стороны, должны быть явно заданы и не получать значения по умолчанию.
Подробнее см. §4.12.5.
Ответ 4
int x;
Integer y;
x == 0; true. because x is initialized to 0 by JVM
x == null; Static Error: Bad type in comparison expression
y == 0; java.lang.NullPointerException
y == null; true, because y is uninitialized
Ответ 5
EDIT: нельзя использовать неинициализированные локальные переменные.
Помимо локальных жителей:
Униализованный int равен 0.
Унифицированное целое число равно null.
Целое - это объект. Униализованные объекты равны нулю.
int - примитивный тип. Специфика языка определяет его неинициализированное значение: 0.
Ответ 6
Этот прослушивал меня раньше, так как описания и поведение кажутся немного непоследовательными. Если вы посмотрите спецификацию языка в разделе раздел 4.12.5 есть раздел, который описывает это и делает джив с тем, что вы наблюдали за компилятором.
Причина, по которой я думаю, что время от времени путается, заключается в том, что другие публикации, которые я прочитал из Sun (например, "Core Java 2" ), описывают поведение, указанное вашим проф. И в другом варианте я использую NetBeans, который позволяет использовать неинициализированные примитивы, но флаги - использование неинициализированных объектов; Однако я не уверен, что это компилятор или выбор IDE.
[EDIT: после просмотра одного из сообщений я считаю, что эта путаница связана с различным поведением для локальных переменных vs fields.]
Ответ 7
Все объекты/переменные в классе инициализируются значениями по умолчанию при создании экземпляра объекта.
По этой причине переменные внутри класса имеют следующие значения:
int x = 0 //default value (value type)
Integer y = null //default values of any object; here Integer is reference type
... и остальное идет аналогичным образом. Надеюсь, мой ответ будет полезен.
Ответ 8
Этот вопрос был задан некоторое время назад, и есть правильные ответы, однако я чувствую, что они могут быть несколько расширены.
Я хотел бы привести пару строк на официальной странице учебников.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Поля, объявленные, но не инициализированные, будут установлены разумным значением по умолчанию компилятором
Локальные переменные несколько отличаются; компилятор никогда не присваивает значение по умолчанию неинициализированной локальной переменной. Доступ к неинициализированной локальной переменной приведет к ошибке времени компиляции.
В Java-примитивах есть значение, которое является числом. (это не так просто, и я настоятельно рекомендую вам больше узнать об этом).
Значение для объекта - это ссылка, из которой можно найти содержимое объекта.
Значение по умолчанию для примитива по существу равно 0, где по умолчанию значение для объекта равно null. (когда неинициализируется и когда поле)
В вашем примере вы пытаетесь сравнить "от 0 до 0, от нуля до нуля и от нуля до нуля".
Факт: null!= 0.
- 0 = числовое значение, не представляющее ничего.
- null = литерал для представления не существующей ссылки. (вы можете увидеть Что такое null в Java? для получения дополнительной информации о null)
FYI: Я считаю, что этот вопрос был отлично удовлетворен Мэтью Флашеном, я просто хотел добавить дополнительную информацию для тех, кто интересуется.