Czy int może mieć wartość NULL w Javie?


155

Czy można intbyć nullw Javie?

Na przykład:

int data = check(Node root);

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

Moim celem jest napisanie funkcji, która zwraca plik int. Wspomniane intjest przechowywane na wysokości węzła, a jeśli węzła nie ma, będzie zerowe i będę musiał to sprawdzić.

Robię to jako zadanie domowe, ale ta konkretna część nie jest częścią pracy domowej, po prostu pomaga mi przejść przez to, co robię.

Dziękuję za komentarze, ale wydaje się, że bardzo niewiele osób faktycznie przeczytało, co jest pod kodem, pytałem, jak inaczej mogę osiągnąć ten cel; łatwo było się domyślić, że to nie działa.


1
Jest to błąd czasu kompilacji.
MayurB

Odpowiedzi:


201

int nie może być zerowa, ale Integer może . Musisz zachować ostrożność podczas rozpakowywania zerowych liczb całkowitych, ponieważ może to spowodować wiele zamieszania i drapania głowy!

np. to:

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

da ci NullPointerException, mimo że obiekt nie jest pusty!

Aby odpowiedzieć na twoje pytanie, jeśli chcesz wskazać brak wartości, zbadam tojava.util.Optional<Integer>


2
Istnieją dobre powody, dla których istnieje klasa Integer, więc używaj jej, gdy potrzeby są istotne.
Blessed Geek,

6
@ h2g2java: Mam nadzieję, że nie myślisz, że możliwość korzystania z nich z domyślną kolekcją jest nieodparta, ponieważ w przypadku rzeczy takich jak HashMap <Integer, Integer> poziom marnotrawstwa jest ogromny i nie jest przekonujący. Dlatego TIntIntHashMap Trove, używając tylko prymitywów, obraca się wokół nieobowiązującego HashMap <Integer, Integer>.
SyntaxT3rr0r

1
int nie może być sprawdzony pod kątem null, jednak możesz bezpiecznie przypisać null do int w Javie, rzutując go na Integer, na przykład jeśli metoda check (root) może zwrócić null, możesz bezpiecznie rzutować ją na int, wykonując coś w rodzaju to: int data = (Integer)check(node);
sactiw

@sactiw - Czy możesz to rozwinąć? Nie jestem pewien, czy rozumiem, do czego zmierzasz
Brian Agnew

7
@BrianAgnew Pozwól, że poprawię to, co tutaj powiedziałem, po prostu się myliłem, w zasadzie nie zdawałem sobie sprawy, że int i = (Integer)null;wyrzuci NPE w czasie wykonywania podczas rozpakowywania.
sactiw

40

Nie. Tylko odwołania do obiektów mogą mieć wartość null, a nie prymitywy.


3
Warto wspomnieć o klasie Integer, która byłaby lepsza, gdyby OP chciał mieć wartość null. Lub może użyć wartości ujemnej, aby wskazać „nie znaleziono”
Glen,

31

Świetny sposób, aby się dowiedzieć:

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

Spróbuj skompilować.


37
Właściwie ... PO już się o tym przekonał, jak w ostatnim zdaniu pytania: łatwo było zorientować się, że to nie działa.
BalusC,

9
Dla potomności prawie 4 lata później - ten kawałek był w późniejszej edycji.
Matt Luongo,

3
ale .. Integer ii = null; int i = ii;skompiluje się, ale wyrzuci wyjątek NullPointerException w czasie wykonywania
premek.v

13

W Javie int jest typem prymitywnym i nie jest uważany za obiekt. Tylko obiekty mogą mieć wartość null. Więc odpowiedź na twoje pytanie brzmi: nie, nie może być zerowa. Ale to nie jest takie proste, ponieważ istnieją obiekty, które reprezentują najbardziej prymitywne typy.

Klasa Integer reprezentuje wartość int, ale może zawierać wartość null. W zależności od checkmetody, możesz zwrócić int lub Integer.

To zachowanie różni się od niektórych bardziej czysto obiektowych języków, takich jak Ruby, gdzie nawet „prymitywne” rzeczy, takie jak ints, są uważane za obiekty.


8

Wraz z powyższą odpowiedzią chciałbym dodać również ten punkt.

Dla typów pierwotnych mamy stałą wielkość pamięci, tj. Dla int mamy 4 bajty, a char mamy 2 bajty. Wartość null jest używana tylko dla obiektów, ponieważ rozmiar pamięci nie jest ustalony.

Więc domyślnie mamy

   int a=0;

i nie

   int a=null;

To samo dotyczy innych typów pierwotnych, dlatego wartość null jest używana tylko dla obiektów, a nie dla typów pierwotnych.


5

Kod nawet się nie skompiluje. Tylko pełnoprawny Objectmoże być null, na przykład Integer. Oto podstawowy przykład pokazujący, kiedy można przetestować wartość null:

Integer data = check(Node root);

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

Z drugiej strony, jeśli check()deklaruje się powrót int, nigdy nie może tak być nulli cały if-elseblok jest wtedy zbędny.

int data = check(Node root);

// do something

Problemy z autoboxingiem nie mają tutaj zastosowania również w przypadku check()deklaracji powrotu int. Jeśli wrócił Integer, możesz zaryzykować NullPointerExceptionprzypisując go do intzamiast Integer. Przypisanie go jako Integeri użycie if-elsebloku byłoby wtedy rzeczywiście obowiązkowe.

Aby dowiedzieć się więcej o autoboxing, sprawdź ten poradnik Sun .


1
Niestety, jeśli "check" zwróci int, a nie liczbę całkowitą, to nie pomoże, ponieważ int (który nie będzie zerowy) zostanie automatycznie umieszczony w polu Integer.
Paul Tomblin,

2
D'oh, to był tylko podstawowy przykład pokazujący, kiedy można przetestować wartość null. Z drugiej strony, jeśli deklaracja powrotu check int, nigdy nie może być zerowa, a całość bloku if jest wtedy zbędna.
BalusC

3

zamiast deklarować jako int izadeklaruj, jak Integer iwtedy możemyi=null;

Integer i;
i=null;

2

Najlepszy byłby obiekt całkowity. Jeśli musisz użyć prymitywów, możesz użyć wartości, która nie istnieje w twoim przypadku użycia. Wzrost ujemny nie istnieje dla ludzi, więc

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

1

Nie, ale int [] może być.

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

Jak @Glen wspomniał w komentarzu, zasadniczo można to obejść na dwa sposoby:

  • użyj wartości „poza zakresem”. Na przykład, jeśli „dane” nigdy nie mogą być ujemne przy normalnym użyciu, należy zwrócić wartość ujemną, aby wskazać, że są nieprawidłowe.
  • Użyj liczby całkowitej. Po prostu upewnij się, że metoda „check” zwraca liczbę całkowitą, a przypisujesz ją do liczby całkowitej, a nie do liczby całkowitej. Ponieważ jeśli po drodze zaangażuje się „int”, automatyczne pakowanie i rozpakowywanie może powodować problemy.

0

Sprawdź, czy w metodzie check () występuje wartość null i zwróć nieprawidłową wartość, taką jak -1 lub zero, jeśli null. Wtedy sprawdzanie dotyczyłoby tej wartości, a nie przekazywania wartości null. To byłoby normalne w dawnych czasach „C”.


0

Żaden typ danych Primitive, taki jak int, boolean, float itp., Nie może przechowywać wartości null (lateral), ponieważ java dostarczyła klasę Wrapper do przechowywania tego samego, co int w Integer, boolean na Boolean.

Np .: Integer i = null;


0

Int nie jest null, może mieć wartość 0, jeśli nie zostanie zainicjowany. Jeśli chcesz, aby liczba całkowita była null, musisz użyć Integer zamiast int. prymitywy nie mają wartości null. domyślna wartość ma dla int to 0.

Typ danych / Wartość domyślna (dla pól)

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

długi ---------------- 0L

float ---------------- 0.0f

podwójne ------------- 0,0d

znak --------------- '\ u0000'

Ciąg --------------- null

boolean ------------ false


-2

Ponieważ prosisz o inny sposób osiągnięcia swojego celu, sugeruję użycie klasy opakowującej:

new Integer(null);

-17

Nie jestem ekspertem, ale wierzę, że nullodpowiednikiem int jest 0.

Na przykład, jeśli utworzysz int[], każdy slot zawiera 0w przeciwieństwie do null, chyba że ustawisz go na coś innego.

W niektórych sytuacjach może to być przydatne.


Po prostu 0 to nie to samo, co null.
Dave Goodchild
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.