Чи може інт бути недійсним на Java?


155

Може intбути nullна Java?

Наприклад:

int data = check(Node root);

if ( data == null ) {
 // do something
} else {
 // do something
}

Моя мета - написати функцію, яка повертає int. Саїд intзберігається у висоті вузла, і якщо вузла немає, він буде нульовим, і мені потрібно буде це перевірити.

Я роблю це для домашніх завдань, але ця конкретна частина не є частиною домашнього завдання, вона просто допомагає мені проникнути те, що я роблю.

Дякую за коментарі, але, здається, дуже мало людей насправді прочитали, що є під кодом, я запитував, як ще я можу досягти цієї мети; було легко зрозуміти, що це не працює.


1
Це похибка часу компіляції.
MayurB

Відповіді:


201

int не може бути нульовим, але Integer може . Ви повинні бути обережними при розпакуванні нульових цілих чисел, оскільки це може призвести до великої плутанини та дряпання голови!

наприклад це:

int a = object.getA(); // getA returns a null Integer

дасть вам NullPointerException, незважаючи на те, що об’єкт не є нульовим!

Щоб продовжити ваше запитання, якщо ви хочете вказати відсутність значення, я би розслідувавjava.util.Optional<Integer>


2
Існують вагомі причини існування класу Integer, тому використовуйте його, коли потреби є переконливими.
Блаженний Гек

6
@ h2g2java: Я сподіваюся, що ви не думаєте, що можливість використовувати їх із колекцією за замовчуванням є переконливим, оскільки для таких матеріалів, як HashMap <Integer, Integer> рівень відходів величезний і непереконливий. Ось чому TIntIntHashMap Trove, використовуючи лише примітиви, обходить коло непереконливого HashMap <Integer, Integer>.
SyntaxT3rr0r

1
int не можна перевірити на null, однак, ви можете сміливо призначити null int в Java, передавши його в Integer, наприклад, якщо метод check (root) може повернути null, ви можете сміливо передавати його до int, роблячи щось подібне це: int data = (Integer)check(node);
sactiw

@sactiw - Чи можете ви докладно? Я не впевнений, що я розумію, до чого ти потрапляєш
Брайан Агнеу

7
@BrianAgnew Дозвольте мені виправити те, що я сказав тут, я зрозумів, що я помилявся, я в основному не розумів, що int i = (Integer)null;буде кидати NPE під час роботи під час розпакування.
sactiw

40

Ні. Тільки посилання на об'єкти можуть бути нульовими, а не примітивними.


3
Варто згадати клас Integer, який був би кращим, якщо ОП бажає нульового значення. Або він міг використати негативне значення для позначення "не знайдено"
Глен

31

Чудовий спосіб дізнатися:

public static void main(String args[]) {
    int i = null;
}

Спробуйте скласти.


37
Насправді .. ОП вже виявило це, як за останньою фразою у своєму питанні: легко було зрозуміти, що це не працює.
BalusC

9
Що стосується нащадків майже через 4 роки - цей біт був опублікований в подальшому редагуванні.
Метт Луонго

3
але .. Integer ii = null; int i = ii;буде компілювати, але кидати NullPointerException під час виконання
premek.v

13

У Java int є примітивним типом, і він не вважається об'єктом. Тільки об'єкти можуть мати нульове значення. Тож відповідь на ваше запитання - ні, вона не може бути нульовою. Але це не так просто, адже є об’єкти, які представляють найпримітивніші типи.

Integer класу представляє значення int, але воно може містити нульове значення. Залежно від вашого checkметоду, ви можете повертати цілий чи цілий число.

Така поведінка відрізняється від деяких більш суто об'єктно орієнтованих мов, таких як Рубі, де навіть "примітивні" речі, такі як ints, вважаються об'єктами.


8

Поряд з усією вищезгаданою відповіддю, я хотів би додати і цю точку.

Для примітивних типів у нас є фіксований об'єм пам'яті, тобто для int у нас є 4 байти, а char - 2 байти. І null використовується лише для об'єктів, оскільки там розмір пам'яті не фіксований.

Отже, за замовчуванням у нас є,

   int a=0;

і ні

   int a=null;

Те саме з іншими примітивними типами, а отже, нульовий використовується лише для об'єктів, а не для примітивних типів.


5

Код навіть не буде компілюватися. Тільки повноцінний Objectможе бути null, як Integer. Ось основний приклад, який показує, коли ви можете протестувати на null:

Integer data = check(Node root);

if ( data == null ) {
 // do something
} else {
 // do something
}

З іншого боку, якщо check()оголошено про повернення int, цього ніколи не може бути, nullі весь if-elseблок тоді буде зайвим.

int data = check(Node root);

// do something

Проблеми з автобоксингом тут також не застосовуються, коли check()оголошено про повернення int. Якщо він повернувся Integer, то ви можете ризикувати, NullPointerExceptionпризначаючи його intзамість Integer. Призначення цього блоку Integerта використання if-elseблоку тоді справді було б обов'язковим.

Щоб дізнатися більше про Autoboxing, перевірити це керівництво Sun .


1
На жаль, якщо "check" повертає int, а не Integer, це не допоможе, оскільки int (який не буде нульовим) буде автоматично введено в поле Integer.
Пол Томблін

2
Да, це був лише основний приклад, щоб показати, коли можна тестувати на null. З іншого боку, якщо чек оголошено поверненням int, він ніколи не може бути нульовим, і ціле, якщо блок тоді буде зайвим.
BalusC

3

замість того, щоб int iзаявляти як оголосити це, як Integer iтоді, ми можемо це зробитиi=null;

Integer i;
i=null;

2

Цілий об'єкт був би найкращим. Якщо ви повинні використовувати примітиви, ви можете використовувати значення, яке не існує у вашому випадку використання. Негативної висоти для людей не існує, тому

public int getHeight(String name){
    if(map.containsKey(name)){
        return map.get(name);
    }else{
        return -1;
    }
}

1

Ні, але int [] може бути.

int[] hayhay = null; //: allowed (int[] is reference type)
int   hayno  = null; //: error   (int   is primitive type)
                     //: Message: incompatible types: 
                     //: <null> cannot be converted to int

0

Як згадував @Glen у коментарі, у вас в основному є два способи цього:

  • використовувати значення "не пов'язане". Наприклад, якщо "дані" ніколи не можуть бути негативними при звичайному використанні, поверніть негативне значення, щоб вказати, що воно недійсне.
  • Скористайтеся цілим числом. Просто переконайтеся, що метод "check" повертає цілий чисел, і ви присвоюєте це Integer не int. Тому що, якщо «інт» потягується на шляху, автоматичний бокс та розблокування можуть спричинити проблеми.

0

Перевірте наявність методу check () у випадку null та поверніть недійсне значення, таке як -1 або zero, якщо null. Тоді перевірка буде на це значення, а не передавати нуль уздовж. Це було б нормальною справою за старого часу "С".


0

Будь-який тип примітивних даних, наприклад int, boolean, float тощо, не може зберігати нуль (бічний), оскільки java надала класу Wrapper для зберігання такого ж, як int до Integer, boolean до Boolean.

Напр .: Integer i = null;


0

Int не є нульовим, він може бути 0, якщо не ініціалізований. Якщо ви хочете, щоб ціле число могло бути нульовим, вам потрібно використовувати Integer замість int. примітиви не мають нульового значення. за замовчуванням має значення int - 0.

Тип даних / Значення за замовчуванням (для полів)

int ------------------ 0

довгий ---------------- 0л

пливуть ---------------- 0,0f

подвійний ------------- 0,0д

char --------------- '\ u0000'

Рядок --------------- null

булева ------------ хибна


-2

Оскільки ви попросите іншого способу досягти своєї мети, пропоную вам скористатися класом обгортки:

new Integer(null);

-17

Я не експерт, але я вважаю, що nullеквівалент int є 0.

Наприклад, якщо ви створюєте int[], кожен слот містить 0на відміну null, якщо ви не встановите його на щось інше.

У деяких ситуаціях це може бути корисним.


Дуже просто, 0 не є нульовим.
Дейв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.