Si se ejecuta el siguiente código,

public class Foo{
    public static void main(String[] args){
        int id = new Bar().getId(); //throws unexpected NullPointerException
    }

    private static class Bar{
        private final Integer id;

        public Bar(){
            this(null);
        }

        public Bar(Integer id){
            this.id = id;
        }

        public Integer getId(){
            return id;
        }
    }
}

obtendrá la siguiente stacktrace,

Exception in thread "main" java.lang.NullPointerException
    at Foo.main(Foo.java:3)

¿Cómo es que no hay ninguna advertencia del compilador o algo? En mi humilde opinión es bastante desagradable la sutileza con la unboxing, o tal vez soy ingenuo.


Añadir a la respuesta proporcionada por @Javier, si usted está utilizando Eclipse, usted necesita hacer lo siguiente para habilitar esta:

  1. Vaya a Ventana > Preferencias > Java > Compilador > Errores/Advertencias
  2. Ampliar Potencial de problemas de programación
  3. Alternar Boxing y unboxing de las conversiones a «Advertencia» o «Error»
  4. Presiona «ACEPTAR»
  • Yo no lo entiendo. Estás preguntando por qué la NPE sucede o esto es sólo una diatriba? ¿Cuál sería el específico de responder a la pregunta?
InformationsquelleAutor mre | 2013-02-20

6 Comentarios

  1. 5

    No sé qué IDE está utilizando, pero Eclipse tiene una opción para activar la advertencia en el boxing y unboxing de conversiones. No es posible detectarlo como un puntero nulo acceso, ya que null no es inmediatamente sin caja, pero a través de Bar.getId().

    La expresión de tipo Entero es sin embalaje en int

    Foo.java línea 3

  2. 5

    Si intenta utilizar cualquier método en un null o hacer algo que no tiene sentido con un null, lanza un NullPointerException.

    Autounboxing se implementa con el [Integer object].intValue() método (o similar), por lo que lanza un NullPointerException porque usted no puede tener null invocar a un método.

    Espero que esto ayude!

    • +1 para que poco acerca de intValue detrás de las escenas, gracias
  3. 4

    parece que este comportamiento se documenta en el JDK™ 5.0 Documentación,

    ..que en gran medida puede ignorar la distinción entre int y Integer, con
    un par de advertencias. Un Integer expresión puede tener un valor nulo. Si su
    programa intenta autounbox null, lanzará una NullPointerException.

  4. 0

    NullPointerException es un RuntimeException de IDE no puede detectar cuando se compila el código.

    Lugar, una buena práctica es comprobar null antes de unboxing.

    int getId(){
        if(id!=null){
            return id;
        }
        //return other or throw a checked exception.
    }
  5. 0

    Parece perfectamente razonable el tiempo de ejecución de excepción. Si el código principal fue:

    public static void main(String[] args){        
        Integer idObj = new Bar().getId();
        int id = idObj;   //throws NullPointerException
    }

    Nadie se sorprendería acerca de la excepción de puntero nulo. El Bar de la clase devuelve un valor nulo, y un objeto nulo puntero no puede ser convertido en un valor simple. La aplicación de la Barra de la clase puede ser cambiado para inicializar la identificación a un valor no nulo. Este bloque de código puede ser compilado en forma independiente de la Barra de clase, y así suposiciones acerca de la dinámica de funcionamiento de la Barra de la clase no debe ser codificado en este bloque de código.

    Este es probablemente obvio, pero la verdadera solución es el uso de int para la identificación de miembro, en lugar de Integer. Esto, entonces, no tiene ningún problema:

    private static class Bar{
        private final int id;
    
        public Bar(){
            this(0);
        }
    
        public Bar(int id){
            this.id = id;
        }
    
        public int getId(){
            return id;
        }
    }

    (Pero supongo que ya eran conscientes de esto 🙂 )

    • yo no dije que la excepción era razonable, me dijo que era inesperado, especialmente desde mi IDE decidió ignorar por defecto.
    • OK, yo estaba tratando de hacer todo lo que se «espera» y «inesperado». Es una excepción en tiempo de ejecución, no es algo que pueda ser necesariamente determina a partir de un análisis estático. Cómo se puede esperar que el IDE para comportarse en esta situación?
    • Yo esperaba que el IDE al menos avisarme por defecto. Como he dicho, creo que es una muy sutil excepción en tiempo de ejecución.
    • Se espera que para determinar todas las situaciones donde es posible obtener un tiempo de ejecución de la NPE? Esto me parece corriendo en contra del teorema de Gödel. Pero me recomiendan evitar el Entero de la clase cuando no la necesita.
    • No, estás siendo hiperbólica. Yo no esperaría que se cuenta para todos los escenarios. Pero parece que los demás pensaban de la misma desde Eclipse proporciona la funcionalidad cuando se trata de boxing/unboxing.
    • Lo siento acerca de ir hiperbólico, estás en lo correcto. Por lo que la advertencia que quieres es simplemente que se está haciendo un tipo en línea, convertir un Entero a un int? Supongo Eclipse puede hacer esto para usted como una advertencia.

  6. 0

    Boxeo no es nada más que azúcar sintáctica para la fundición de un objeto como Entero a la
    nativo equivalente a ‘int’. Los nativos no puede ser nulo, pero los objetos. El boxeo mecanismo no impide que NullPointerExceptions en estos casos.

Dejar respuesta

Please enter your comment!
Please enter your name here