martes, 10 de septiembre de 2019

catch NullPointerException a Worst Practice

A lo largo de mis más de 20 años de experiencia he visto una cantidad bastante significativa de equivocaciones al momento de codificar, y cometido aún muchas más; sin embargo, hasta ahora nunca había visto un catch NullPointerException.
Quizá por ello…




Desconocía la existencia de la siguiente regla PMD (https://pmd.github.io/latest/pmd_rules_java.html)
Issue Info
Avoid catching NullPointerException; consider removing the cause of the NPE.
–  Strict Exceptions
– { } Pmd.Strict Exceptions
Una NullPointerException es una RuntimeException (https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html); es decir, es una excepción no checada (unchecked).
Es decir, es una Exception que no se declara ni se espera su tratamiento. Se entiende entonces que, no debemos realizar throw() de estas, salvo alguna curiosa excepción como el caso de API que lanzan checked exceptions cuando deberían haber sido uncheked exceptions, así como tampoco tratarlas con un try-catch.
De hecho, hacerlo esta considerado como una pésima práctica.
En lugar de ello, debemos cuidar nuestra codificación para procurar evitarlas.
Por ejemplo, en lugar de un código como este…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * Find all by rol.
 *
 * @param rol         the rol
 * @param soloActivos the solo activos
 * @return the sets the
 *
 */
@Override
public Set<Pantalla> findAllByRol(Rol rol, boolean soloActivos) {
 
    LOGGER.info("Ejecutando findAllByRol()");
 
    Set<Permiso> permisos = rol.getPermisos();
    Set<Pantalla> result = new HashSet<>();
    try {
        Iterator<Permiso> i = permisos.iterator();
        while(i.hasNext()){
            Permiso p = i.next();
            if (soloActivos){
                if(p.getActivo() == 1 && p.getPantalla().getActivo() == 1){
                    result.add(p.getPantalla());
                }
            } else {
                result.add(p.getPantalla());
            }
        }
    }catch(NullPointerException ex) {
        LOGGER.error("No se encontraron permisos para el rol actual", ex);
    }
    return result;
}
Podríamos procurar una implementación como esta…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * Find all by rol.
 *
 * @param rol         the rol
 * @param soloActivos the solo activos
 * @return the sets the
 *
 */
@Override
public Set<Pantalla> findAllByRol(Rol rol, boolean soloActivos) {
 
    LOGGER.info("Ejecutando findAllByRol()");
 
    Set<Permiso> permisos = rol.getPermisos();
    Set<Pantalla> result = new HashSet<>();
 
    if(permisos!=null && !permisos.isEmpty()) {
        Iterator<Permiso> i = permisos.iterator();
        while(i.hasNext()){
            Permiso p = i.next();
            if (soloActivos){
                if(p.getActivo() == 1 && p.getPantalla().getActivo() == 1){
                    result.add(p.getPantalla());
                }
            } else {
                result.add(p.getPantalla());
            }
        }
    }
 
    return result;
}
Recuerda, al menos en programación, la mejor Excepción es aquella que no se lanza.
Si quieres aprender un poco acerca del tratamiento de excepciones te recomiendo que revises el siguiente material (http://www.cursohibernate.es/doku.php?id=patrones:excepciones); el cual, a pesar de ser bastante básico, plasma con perfecta claridad los principios elementales del tratamiento de excepciones.

Espero que te haya parecido útil e interesante este artículo.
No olvides visitarme en mi perfil de GitHub: https://github.com/era5mx.
………….
Quiero man.tener.me informado: Seguir en Twitter @eldavid_oficial https://twitter.com/eldavid_oficial
Regálame un ME GUSTA. Y si eres solidario, COMPARTE para que otros puedan aprovecharlo

No hay comentarios.:

Publicar un comentario

Nota: sólo los miembros de este blog pueden publicar comentarios.