Подтвердить что ты не робот

Неинициализированный 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 истинны? Объяснение о том, почему было бы очень полезно, спасибо.

4b9b3361

Ответ 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: Я считаю, что этот вопрос был отлично удовлетворен Мэтью Флашеном, я просто хотел добавить дополнительную информацию для тех, кто интересуется.