Você notou java.lang.NullPointerException (NPE)? 8 práticas recomendadas para evitar o NPE em tempo de execução em Java
Publicados: 2020-10-07
Evite Null Pointer Exception em Java e Java Dicas e práticas recomendadas para evitar NullPointerException em Java.
Como desenvolvedor Java, tenho certeza que você deve ter enfrentado Null Pointer Exception (NPE) a partir do primeiro dia. Na maioria dos casos, a exceção NPE mostra um rastreamento de pilha claro que aponta a causa raiz do mesmo, mas no caso de um aplicativo de nível corporativo grande no qual você tem centenas de classes, torna-se um pesadelo descobrir a causa raiz real.
O que é a exceção de ponteiro nulo (NPE)?
NullPointerException (NPE)
é uma exceção que ocorre quando você tenta usar uma referência que aponta para nenhum local na memória (null) como se estivesse referenciando um objeto.
Chamar um método em uma referência null
ou tentar acessar um campo de uma referência nula acionará um NPE. Esta é a causa mais comum.
De acordo com o JavaDoc, abaixo estão as principais causas para o NPE:
- Lançando
null
como se fosse um valorThrowable
. - Chamando o método de instância de um objeto
null
. - Acessando ou modificando o campo de um objeto
null
. - Tomando o comprimento de
null
como se fosse uma matriz. - Acessando ou modificando os slots de
null
como se fosse um array.
Agora a questão real é como evitar java.lang.NullPointerException em tempo de execução? Neste tutorial, veremos alguns exemplos que criam NPE em tempo de execução e as etapas que precisamos executar para resolver isso.
Vamos criar o NPE em tempo de execução 1º. Dê uma olhada no exemplo abaixo CrunchifyNullPointerExceptionTips.java
Vamos criar NPE de 3 maneiras diferentes
- O NPE será lançado se você estiver tentando acessar o objeto nulo
- O NPE será lançado se você estiver tentando converter String nula
- O NPE será lançado se você estiver tentando acessar o objeto nulo durante a inicialização da classe
Criar classe CrunchifyNullPointerExceptionTips.java
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
package crunchify . com . tutorial ; /** * @author Crunchify.com * Have you Noticed java.lang.NullPointerException (NPE)? 8 Best practices to avoid runtime NPE in Java */ public class CrunchifyNullPointerExceptionTips { public static void main ( String [ ] args ) { try { // Example 1: NPE will be thrown if you are trying to access null Object CrunchifyNPE1 ( ) ; } catch ( NullPointerException crunchifyNPE1 ) { System . out . println ( "Exception in CrunchifyNPE1()" ) ; crunchifyNPE1 . printStackTrace ( ) ; } try { // Example 2: NPE will be thrown if you are trying to convert null String CrunchifyNPE2 ( ) ; } catch ( NullPointerException crunchifyNPE2 ) { System . out . println ( "\nException in CrunchifyNPE2()" ) ; // printStackTrace(): Prints this throwable and its backtrace to the standard error stream. // This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err. // The first line of output contains the result of the toString() method for this object. // Remaining lines represent data previously recorded by the method fillInStackTrace(). crunchifyNPE2 . printStackTrace ( ) ; } try { // Example 3: NPE will be thrown if you are trying to access null Object during Class Initialization CrunchifyNPETest npe = new CrunchifyNPETest ( ) ; npe . getName ( ) ; // NullPointerException: Thrown when an application attempts to use null in a case where an object is required. These include: // - Calling the instance method of a null object. // - Accessing or modifying the field of a null object. // - Taking the length of null as if it were an array. // - Accessing or modifying the slots of null as if it were an array. // - Throwing null as if it were a Throwable value. } catch ( NullPointerException crunchifyNPE3 ) { System . out . println ( "\n Exception in CrunchifyNPETest()" ) ; crunchifyNPE3 . printStackTrace ( ) ; } } private static void CrunchifyNPE1 ( ) { Object crunchifyObj = null ; // hasCode(): Returns a hash code value for the object. // This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. crunchifyObj . hashCode ( ) ; } private static void CrunchifyNPE2 ( ) { String crunchifyString ; crunchifyString = "https://crunchify.com" ; // The line 40 declares a variable named "crunchifyString", but, it does not contain a primitive value. Instead it contains a pointer (because the type is String // which is a reference type). Since you did not say as yet what to point to Java sets it to null, meaning "I am pointing at nothing". // In line 41, the new keyword is used to instantiate (or create) an object of type String and the pointer variable "crunchifyString" is assigned this // object. You can now reference the object using the dereferencing operator . (a dot). System . out . println ( "\nvalue: " + crunchifyString . toString ( ) + ", length: " + crunchifyString . length ( ) ) ; System . out . println ( "No NPE exception on line 51" ) ; // Now Let's create NPE String crunchifyString2 = null ; System . out . println ( crunchifyString2 . toString ( ) ) ; } } class CrunchifyNPETest { private String crunchifyName ; public void setName ( String name ) { this . crunchifyName = name ; } public void getName ( ) { printName ( crunchifyName ) ; } private void printName ( String s ) { System . out . println ( s + " (" + s . length ( ) + ")" ) ; } } |
Resultado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Exception in CrunchifyNPE1 ( ) java . lang . NullPointerException : Cannot invoke "Object.hashCode()" because "crunchifyObj" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE1 ( CrunchifyNullPointerExceptionTips . java : 59 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 14 ) value : https : //crunchify.com, length: 21 No NPE exception on line 51 Exception in CrunchifyNPE2 ( ) Exception in CrunchifyNPETest ( ) java . lang . NullPointerException : Cannot invoke "String.toString()" because "crunchifyString2" is null at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . CrunchifyNPE2 ( CrunchifyNullPointerExceptionTips . java : 75 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 23 ) java . lang . NullPointerException : Cannot invoke "String.length()" because "s" is null at crunchify . com . tutorial . CrunchifyNPETest . printName ( CrunchifyNullPointerExceptionTips . java : 92 ) at crunchify . com . tutorial . CrunchifyNPETest . getName ( CrunchifyNullPointerExceptionTips . java : 88 ) at crunchify . com . tutorial . CrunchifyNullPointerExceptionTips . main ( CrunchifyNullPointerExceptionTips . java : 38 ) Process finished with exit code 0 |
Bem, existem algumas dicas e truques que podemos usar para evitar NullPointerException em tempo de execução. Vamos dar uma olhada.

Dica 1:
O Eclipse / IntelliJ IDE tentará mostrar o NPE no espaço de trabalho. Corrija seu código apenas durante o desenvolvimento.

Dica 2:
Adicione crunchifyI
sNullorEmpty
()
antes de uma operação no objeto. Adicione isso a CrunchifyNullPointerExceptionTips.java
1 2 3 4 5 6 7 8 |
public static boolean crunchifyIsNullOrEmpty ( String crunchifyStr ) { if ( crunchifyStr == null ) return true ; else if ( crunchifyStr . trim ( ) . equals ( "" ) ) return true ; else return false ; } |
No programa java acima, as linhas 55 e 56 serão substituídas por isso.
1 2 3 4 5 6 |
String crunchifyString2 = null ; if ( ! crunchifyIsNullOrEmpty ( crunchifyString2 ) ) { System . out . println ( crunchifyString2 . toString ( ) ) ; } else { System . out . println ( "crunchifyString2 is null" ) ; } |
Dica 3:
Verifique se String é null
ou vazio após a operação trim().
1 2 3 |
public static boolean isNullOrEmptyAfterTrim ( String crunchifyStr ) { return ( crunchifyStr == null | | crunchifyStr . trim ( ) . length ( ) == 0 ) ; } |
Dica 4:
Sempre use Try Catch block
para evitar o processo de tempo de execução ininterrupto.
1 2 3 4 5 |
try { CrunchifyNPE1 ( ) ; } catch ( NullPointerException npe ) { System . out . println ( "Exception in CrunchifyNPE1()" + npe ) ; } |
Dica 5:
Collections.emptyList()
é preferido devido ao melhor manuseio de genéricos.
Dica 6:
Usar Java Assertions
Uma asserção é uma declaração que permite testar suas suposições sobre seu código. Por exemplo, se você escrever um método que retorne o nome no sistema, poderá declarar que o otherName retornando se String for nulo.
O uso básico de asserções seria:
1 2 3 4 5 6 7 8 |
assert < Expression > ; // or another usage is assert < Expression1 > : < Expression2 > ; // in our program add line below. private void printName ( String s ) { assert ( s ! = null ) : "Name must be not null" ; System . out . println ( s + " (" + s . length ( ) + ")" ) ; } |
Mas há um problema: Assertion não está disponível no ambiente de produção e não devemos usar Assertion com nenhuma lógica de negócios.
Dica 7:
Tente usar as verificações containsKey()
, containsValue()
, contains()
.
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 |
package com . crunchify . tutorial ; import java . util . * ; /** * @author Crunchify.com * */ public class CrunchifyContainsKeyExample { public static void main ( String args [ ] ) { HashMap < Integer , String > crunchifyMap = new HashMap < Integer , String > ( ) ; // populate hash map crunchifyMap . put ( 1 , "Crunchify" ) ; crunchifyMap . put ( 2 , "wordpress" ) ; crunchifyMap . put ( 3 , "java tutorials" ) ; // check existence of key 4 if ( crunchifyMap . containsKey ( 4 ) ) { System . out . println ( "Check if key 2 exists: " + crunchifyMap . get ( 4 ) ) ; } else { System . out . println ( "NPE for value 4 avoided" ) ; } } } |
Dica 8:
Como conclusão, é sempre uma boa prática cuidar do NPE durante o desenvolvimento, em vez de depurar na produção em tempo de execução. Existem várias outras dicas e truques disponíveis usando Spring Framework Annotation, Factory Pattern
, Null Object Pattern etc. Mas vou resumir isso agora.
Vai publicar novo tutorial provavelmente em uma semana sobre este. Fique ligado.
Você deseja adicionar algo a este tutorial OU encontrou um problema, entre em contato e forneça seus comentários.