Para programadores Java, null é uma dor de cabeça. Muitas vezes você é assediado por exceções de ponteiro nulo (NPE). Até o inventor do Java admitiu que isso foi um grande erro de sua parte. Por que Java mantém nulo? O nulo já existe há algum tempo e acho que os inventores do Java sabiam que o nulo causava mais problemas do que os problemas que resolvia, mas o nulo ainda está com o Java.
Estou cada vez mais surpreso, porque o princípio de design do Java é simplificar as coisas, é por isso que não se perde tempo com ponteiros, sobrecarga de operadores e implementação de herança múltipla. Null é exatamente o oposto. Bem, eu realmente não sei a resposta para essa pergunta, o que eu sei é que não importa o quão criticado o null seja pelos desenvolvedores Java e pela comunidade de código aberto, temos que coexistir com o null. Em vez de lamentar a existência de null, devemos aprender melhor sobre null e garantir que null seja usado corretamente.
Por que você precisa aprender nulo em Java? Porque se você não prestar atenção em null, Java fará você sofrer de NullPointerException e você aprenderá uma lição dolorosa. A programação energética é uma arte que sua equipe, clientes e usuários irão valorizar mais. Na minha experiência, um dos principais motivos para exceções de ponteiro nulo é o conhecimento insuficiente de nulo em Java. Muitos de vocês já estão familiarizados com null, mas para aqueles que não estão, vocês podem aprender algo antigo e novo sobre null. Vamos reaprender alguns conhecimentos importantes sobre null em Java.
O que é nulo em Java?
Como eu disse, null é um conceito muito importante em Java. A intenção original de null é representar algo que está faltando, como um usuário, recurso ou outras coisas ausentes. No entanto, um ano depois, a problemática exceção do ponteiro nulo causou muito assédio aos programadores Java. Neste material, aprenderemos os detalhes básicos da palavra-chave nula em Java e exploraremos algumas técnicas para minimizar verificações de nulos e como evitar exceções desagradáveis de ponteiro nulo.
1) Em primeiro lugar, null é uma palavra-chave em Java, como public, static e final. Faz distinção entre maiúsculas e minúsculas, você não pode escrever null como Null ou NULL, o compilador não os reconhecerá e reportará um erro.
Copie o código do código da seguinte forma:
Objeto obj = NULL; // Não está bem
Objeto obj1 = null //Ok
Programadores que usam outras linguagens podem ter esse problema, mas agora o uso do IDE tornou esse problema trivial. Agora, quando você digita código, IDEs como Eclipse e Netbeans podem corrigir esse erro. Mas usando outras ferramentas como bloco de notas, Vim e Emacs, esse problema desperdiçará seu precioso tempo.
2) Assim como todo tipo primitivo tem um valor padrão, por exemplo, o valor padrão de int é 0, o valor padrão de booleano é falso e null é o valor padrão de qualquer tipo de referência. de todos os tipos de objetos. Assim como você cria uma variável booleana que tem false como valor padrão, qualquer variável de referência em Java tem null como valor padrão. Isso é verdade para todas as variáveis, como variáveis de membro, variáveis locais, variáveis de instância, variáveis estáticas (mas quando você usa uma variável local não inicializada, o compilador irá avisá-lo). Para demonstrar esse fato, você pode observar essa variável de referência criando uma variável e depois imprimindo seu valor, conforme mostrado no código a seguir:
Copie o código do código da seguinte forma:
objeto estático privado myObj;
public static void main(String args[]){
System.out.println("Qual é o valor de myObjc: " + myObj);
}
Qual é o valor de myObjc: null
Isto é verdade para objetos estáticos e não estáticos. Como você pode ver aqui, defini myObj como uma referência estática para poder usá-la diretamente no método principal. Observe que o método principal é um método estático e não pode usar variáveis não estáticas.
3) Queremos esclarecer alguns mal-entendidos. Null não é um objeto nem um tipo. Você pode atribuí-lo a qualquer tipo de referência.
Copie o código do código da seguinte forma:
String str = null; // null pode ser atribuído a String
Integer itr = null; // você também pode atribuir null a Integer
Double dbl = null; // null também pode ser atribuído a Double
String myStr = (String) null; // null pode ser convertido em tipo String
Integer myItr = (Integer) null; // também pode ser convertido em tipo Integer;
Double myDbl = (Double) null; // sim, é possível, sem erro
Você pode ver que converter null para qualquer tipo de referência é possível em tempo de compilação e execução e não lançará uma exceção de ponteiro nulo em tempo de execução.
4) Nulo pode ser atribuído a variáveis de referência, mas você não pode atribuir nulo a variáveis de tipo básico, como int, double, float e boolean. Se você fizer isso, o compilador gerará um erro como este:
Copie o código do código da seguinte forma:
int i = null; // tipo incompatível: não é possível converter de nulo para int
short s = null; // tipo incompatível: não é possível converter de nulo para curto
byte b = null: // tipo incompatível: não é possível converter de nulo para byte
double d = null; //incompatibilidade de tipo: não é possível converter de nulo para duplo
Inteiro itr = null; // está tudo bem
int j = itr; // isso também está ok, mas NullPointerException em tempo de execução
Como você pode ver, ao atribuir null diretamente a um tipo primitivo, ocorre um erro de compilação. Mas se você atribuir nulo ao objeto da classe wrapper e, em seguida, atribuir o objeto aos respectivos tipos básicos, o compilador não o reportará, mas você encontrará uma exceção de ponteiro nulo em tempo de execução. Isso é causado pelo unboxing automático em Java, que veremos no próximo item.
5) Qualquer classe wrapper contendo um valor nulo lançará uma exceção de ponteiro nulo quando Java descompacta e gera tipos de dados básicos. Alguns programadores cometem o erro de pensar que o autoboxing converterá null para o valor padrão do respectivo tipo básico, como 0 para int e false para tipo booleano, mas isso não é correto, conforme mostrado abaixo:
Copie o código do código da seguinte forma:
Inteiro iAmNull = null;
int i = iAmNull; // Lembre-se - Sem erro de compilação
Mas ao executar o trecho de código acima, você verá no console que o thread principal lança uma exceção de ponteiro nulo. Muitos desses erros ocorrem ao usar valores de chave HashMap e Integer. Um erro aparecerá quando você executar o código a seguir.
Copie o código do código da seguinte forma:
importar java.util.HashMap;
importar java.util.Map;
/**
* Um exemplo de Autoboxing e NullPointerExcpetion
*
* @autor WINDOWS 8
*/
teste de classe pública {
public static void main(String args[]) lança InterruptedException {
Mapa numberAndCount = new HashMap<>();
int[] números = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
for(int i : números){
int contagem = númeroAndCount.get(i);
numberAndCount.put(i, count++); // NullPointerException aqui
}
}
}
Saída:
Copie o código do código da seguinte forma:
Exceção no thread "principal" java.lang.NullPointerException
em Test.main(Test.java:25)
Este código parece muito simples e livre de erros. Tudo o que você faz é descobrir quantas vezes um número aparece em um array, que é a técnica típica para localizar duplicatas em arrays Java. O desenvolvedor primeiro obtém o valor anterior, depois adiciona um e, finalmente, coloca o valor de volta no Mapa. O programador pode pensar que ao chamar o método put, o boxe automático irá lidar com o boxe de int em Interger, mas ele esquece que quando um número não tem um valor de contagem, o método get() do HashMap retornará nulo e não 0 , porque o valor padrão de Inteiro é nulo e não 0. O Autoboxing retornará um NullPointerException ao passar um valor nulo para uma variável int. Imagine se esse código estivesse dentro de um ninho if e não estivesse rodando em um ambiente de QA, mas uma vez colocado em um ambiente de produção, BOOM :-)
6) Se uma variável de tipo de referência com valor nulo for usada, a operação instanceof retornará falso:
Copie o código do código da seguinte forma:
Inteiro iAmNull = null;
if(iAmNull instância de número inteiro){
System.out.println("iAmNull é uma instância de Integer");
}outro{
System.out.println("iAmNull NÃO é uma instância de Integer");
}
Saída:
Copie o código do código da seguinte forma:
eu
AmNull NÃO é uma instância de Integer
Este é um recurso muito importante da operação instanceof, tornando-o útil para verificações de conversão de tipo.
7) Você deve saber que não pode chamar um método não estático para usar uma variável de tipo de referência com um valor nulo. Isso lançará uma exceção de ponteiro nulo, mas você pode não saber que pode usar métodos estáticos para usar uma variável de tipo de referência com um valor nulo. Como os métodos estáticos usam ligação estática, exceções de ponteiro nulo não serão lançadas. Aqui está um exemplo:
Copie o código do código da seguinte forma:
Teste de classe pública {
public static void main(String args[]){
Testando meuObjeto = null;
meuObject.iAmStaticMethod();
meuObject.iAmNonStaticMethod();
}
privado estático void iAmStaticMethod(){
System.out.println("Sou um método estático, pode ser chamado por referência nula");
}
privado void iAmNonStaticMethod(){
System.out.println("Eu não sou um método estático, não me chame de null");
}
Saída:
Copie o código do código da seguinte forma:
Eu sou um método estático, pode ser chamado por referência nula
Exceção no thread "principal" java.lang.NullPointerException
em Testing.main(Testing.java:11)
8) Você pode passar null para o método, e o método pode receber qualquer tipo de referência. Por exemplo, public void print(Object obj) pode chamar print(null) assim. Do ponto de vista da compilação, tudo bem, mas o resultado depende inteiramente do método. Métodos seguros para nulos, como o método print neste exemplo, não lançam uma NullPointerException e simplesmente saem normalmente. Se a lógica de negócios permitir, é recomendável usar métodos seguros para nulos.
9) Você pode usar operações == ou! = para comparar valores nulos, mas não pode usar outros algoritmos ou operações lógicas, como menor que ou maior que. Ao contrário do SQL, null==null retornará true em Java, conforme mostrado abaixo:
Copie o código do código da seguinte forma:
teste de classe pública {
public static void main(String args[]) lança InterruptedException {
String abc = nulo;
String cde = nulo;
if(abc == cde){
System.out.println("null == null é verdadeiro em Java");
}
if(nulo!=nulo){
System.out.println("null! = null é falso em Java");
}
// verificação nula clássica
if(abc==nulo){
//faça alguma coisa
}
// não está ok, erro de tempo de compilação
if(abc > nulo){
}
}
}
Saída:
Copie o código do código da seguinte forma:
null == null é verdadeiro em Java
Tudo isso é nulo em Java. Com alguma experiência em programação Java e usando truques simples para evitar exceções de ponteiro nulo, você pode tornar seu código seguro para nulos. Como null é frequentemente usado como um valor vazio ou não inicializado, é uma fonte de confusão. Para métodos, também é muito importante registrar como o método se comporta quando null é usado como parâmetro. Resumindo, lembre-se de que null é o valor padrão de qualquer variável de tipo de referência. Você não pode usar referências nulas para chamar quaisquer métodos de instância ou variáveis de instância em Java.