¿Puede un int ser nulo en Java?

155

¿Puede un intestar nullen Java?

Por ejemplo:

int data = check(Node root);

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

Mi objetivo es escribir una función que devuelva un int. Dicho intestá almacenado en la altura de un nodo, y si el nodo no está presente, será nulo, y tendré que verificarlo.

Estoy haciendo esto para la tarea, pero esta parte específica no es parte de la tarea, solo me ayuda a superar lo que estoy haciendo.

Gracias por los comentarios, pero parece que muy pocas personas han leído realmente lo que está bajo el código, estaba preguntando cómo más puedo lograr este objetivo; fue fácil darse cuenta de que no funciona.

user220755
fuente
1
Es un error de tiempo de compilación.
MayurB

Respuestas:

201

int no puede ser nulo, pero Integer puede . ¡Debe tener cuidado al desempaquetar enteros nulos ya que esto puede causar mucha confusión y rascarse la cabeza!

por ejemplo esto:

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

te dará un NullPointerException, a pesar de que el objeto no sea nulo!

Para dar seguimiento a su pregunta, si desea indicar la ausencia de un valor, investigaríajava.util.Optional<Integer>

Brian Agnew
fuente
2
Existen buenas razones para la existencia de la clase Integer, así que úsela cuando las necesidades sean convincentes.
Beato Geek
66
@ h2g2java: Espero que no pienses que poder usarlos con la colección predeterminada es convincente porque para cosas como HashMap <Integer, Integer> el nivel de desperdicio es enorme y no convincente. Es por eso que el TIntIntHashMap de Trove, que usa solo primitivas, corre alrededor del HashMap <Integer, Integer> no convincente.
SyntaxT3rr0r
1
int no puede verificarse como nulo, sin embargo, puede asignar nulo de manera segura a int en Java convirtiéndolo en Integer, por ejemplo, si el método check (root) puede devolver nulo, puede convertirlo a int de manera segura haciendo algo como esto: int data = (Integer)check(node);
sactiw
@sactiw - ¿Puedes dar más detalles? No estoy seguro de entender a qué te refieres
Brian Agnew
77
@BrianAgnew Permítanme rectificar lo que dije aquí, estaba completamente equivocado, básicamente no me di cuenta de que int i = (Integer)null;arrojaría NPE en tiempo de ejecución mientras lo desempaquetaba.
Sactiw
40

No. Solo las referencias a objetos pueden ser nulas, no primitivas.

Ignacio Vazquez-Abrams
fuente
3
Vale la pena mencionar la clase Integer, que sería mejor si el OP desea un valor nulo. O podría usar un valor negativo para indicar "no encontrado"
Glen
31

Una excelente manera de descubrirlo:

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

Intenta compilar.

Matt Luongo
fuente
37
En realidad ... El OP ya lo descubrió él mismo según la última frase de su pregunta: fue fácil darse cuenta de que no funciona.
BalusC
9
Para la posteridad casi 4 años después, ese bit estaba en una edición posterior.
Matt Luongo
3
pero ... Integer ii = null; int i = ii;compilará pero lanzará NullPointerException en tiempo de ejecución
premek.v
13

En Java, int es un tipo primitivo y no se considera un objeto. Solo los objetos pueden tener un valor nulo. Entonces la respuesta a su pregunta es no, no puede ser nula. Pero no es tan simple, porque hay objetos que representan los tipos más primitivos.

La clase Integer representa un valor int, pero puede contener un valor nulo. Dependiendo de su checkmétodo, podría devolver un int o un número entero.

Este comportamiento es diferente de algunos lenguajes más puramente orientados a objetos como Ruby, donde incluso cosas "primitivas" como ints se consideran objetos.

Jonathon Faust
fuente
8

Junto con toda la respuesta anterior, me gustaría agregar este punto también.

Para los tipos primitivos, tenemos un tamaño de memoria fijo, es decir, para int tenemos 4 bytes y char tenemos 2 bytes. Y nulo se usa solo para objetos porque el tamaño de la memoria no es fijo.

Entonces, por defecto tenemos,

   int a=0;

y no

   int a=null;

Lo mismo ocurre con otros tipos primitivos y, por lo tanto, nulo solo se usa para objetos y no para tipos primitivos.

Shoaib Chikate
fuente
5

El código ni siquiera se compilará. Solo un digno Objectpuede ser null, como Integer. Aquí hay un ejemplo básico para mostrar cuándo puede probar nulo:

Integer data = check(Node root);

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

Por otro lado, si check()se declara que regresa int, nunca puede serlo nully todo el if-elsebloque es superfluo.

int data = check(Node root);

// do something

Los problemas de autoboxing no se aplican aquí también cuando check()se declara que regresa int. Si hubiera regresado Integer, entonces puede arriesgarse NullPointerExceptional asignarlo a un en intlugar de Integer. Asignarlo como un Integery usar el if-elsebloque habría sido obligatorio.

Para obtener más información sobre autoboxing, comprobar esta guía Sun .

BalusC
fuente
1
Desafortunadamente, si "check" devuelve un int en lugar de un Integer, esto no ayudará, porque el int (que no será nulo) se encuadrará automáticamente en el Integer.
Paul Tomblin
2
Oh, eso fue solo un ejemplo básico para mostrar cuándo puedes probar nulo. Por otro lado, si se declara que el cheque devuelve int, nunca puede ser nulo y todo si el bloque es superfluo.
BalusC
3

en lugar de declarar como int ideclararlo como Integer ientonces podemos haceri=null;

Integer i;
i=null;
Minati
fuente
2

Objeto entero sería lo mejor. Si debe usar primitivas, puede usar un valor que no existe en su caso de uso. La altura negativa no existe para las personas, entonces

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

No, pero int [] puede ser.

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
JMI MADISON
fuente
0

Como @Glen mencionó en un comentario, básicamente tiene dos formas de evitar esto:

  • use un valor "fuera de límite". Por ejemplo, si los "datos" nunca pueden ser negativos en el uso normal, devuelva un valor negativo para indicar que no es válido.
  • Usa un número entero. Solo asegúrese de que el método "check" devuelva un número entero y lo asigne a un número entero, no a un int. Porque si un "int" se involucra en el camino, el boxeo y el unboxing automáticos pueden causar problemas.
Paul Tomblin
fuente
0

Verifique nulo en su método check () y devuelva un valor no válido como -1 o cero si es nulo. Entonces la comprobación sería para ese valor en lugar de pasar el valor nulo. Esto sería algo normal en los viejos tiempos 'C'.

usuario3550884
fuente
0

Cualquier tipo de datos primitivo como int, boolean o float, etc. no puede almacenar el nulo (lateral), ya que java ha proporcionado la clase Wrapper para almacenar lo mismo como int a Integer, boolean a Boolean.

Por ejemplo: entero i = nulo;

Sachin Pete
fuente
0

Un int no es nulo, puede ser 0 si no se inicializa. Si desea que un entero pueda ser nulo, debe usar Integer en lugar de int. Las primitivas no tienen valor nulo. el valor predeterminado para int es 0.

Tipo de datos / valor predeterminado (para campos)

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

largo ---------------- 0L

flotador ---------------- 0.0f

doble ------------- 0.0d

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

Cadena --------------- nulo

booleano ------------ falso

Mohammad Fathi
fuente
-2

Dado que solicita otra forma de lograr su objetivo, le sugiero que use una clase de contenedor:

new Integer(null);
Arenoso
fuente
-17

No soy un experto, pero creo que el nullequivalente para un int es 0.

Por ejemplo, si crea un int[], cada ranura contiene 0en lugar de null, a menos que lo configure en otra cosa.

En algunas situaciones, esto puede ser útil.

Lahn
fuente
Muy simple, 0 no es lo mismo que nulo.
Dave Goodchild