Como resolver NullPointerException sem testar com o IF se objeto está null

5 respostas
U

Boa noite. É o seguinte Do jeito que o código está, OK, está imprimindo que não encontrou contato pois não tenho o id 2 cadastrado mesmo. Mas gostaria de saber se tem outra solução que não seja testar se o meu objeto está null. Por exemplo Try/Catch !? Faz sentido!?

if(rs.next()){
			Contato contato = new Contato();
			contato.setNome(rs.getString("nome"));
			contato.setEmail(rs.getString("email"));
			contato.setEndereco(rs.getString("endereco"));
			Calendar data = Calendar.getInstance();
			data.setTime(rs.getDate("dataNascimento"));
			contato.setDataNascimento(data);
			return contato;
		}else{
			return null;
		}
	} catch (SQLException e) {
		throw new DAOException();
	}

}



public static void main(String[] args) {

	SimpleDateFormat dataFormatada = new SimpleDateFormat("dd-MM-yyyy");
	ContatoDao dao = new ContatoDao();
	Contato contato = new Contato();
	
	contato = dao.pesquisaContatoPorId(2);
	
	if(contato != null){
	System.out.println("Nome: " +contato.getNome());
	System.out.println("Email: " +contato.getEmail());
	System.out.println("Endereco: " +contato.getEndereco());
	//chama o format do objeto dataFormatadapara formatar a data que veio do banco
	System.out.println("Data Nascimento: " +dataFormatada.format(contato.getDataNascimento().getTime()));
	}else{
		System.out.println("Contato não encontrado");
	}
	

}

}

5 Respostas

M
Hashtable<Integer, String> tabela = new Hashtable<>();
        long tempo1 = System.currentTimeMillis();
        String concat = " ms";
        for (int i = 0, l = 1000000; i < l; i++) {
            String dado = tabela.get(i);
            if (dado != null) {
                concat += dado.substring(1);
            }
        }
        long tempo2 = System.currentTimeMillis();
        for (int i = 0, l = 1000000; i < l; i++) {
            try {
                concat += tabela.get(i).substring(1);
            } catch (RuntimeException re) {
            }
        }
        long tempo3 = System.currentTimeMillis();
        System.out.println("Tempo if: " + (tempo2 - tempo1) + concat);
        System.out.println("Tempo try/catch: " + (tempo3 - tempo2) + concat);
        /**
         * Resultado meu teste:
         * Tempo if: 31 ms
         * Tempo try/catch: 641 ms
         */

Não necessariamente você precisa usar um if para fazer as coisas, você também pode usar um bloco try/catch. Como dá para ver no meu exemplo acima, em termos de processamento é muito mais rápido fazer processar um simples if do que uma exceção, no Java por baixo dos panos, você não passa os objetos como parâmetro, você passa apenas a referência do objeto, e no caso do objeto nulo, sua referência não aponta para lugar nenhum. É até mesmo por isso que não dá para comparar duas String com ==, já que neste caso, você compara apenas a referência do objeto.

Em Java, é muito comum as pessoas usarem os recursos de exceções de modo equivocado, criar uma classe que estenda indiretamente de Throwable (uma classe de exceção), é um recurso destinado aos desenvolvedores de API e de Frameworks, já que é muito difícil prever como o programador de usara a API ou o Framework o utilizara, e já usar o try/catch é um recurso para o programador final gerenciar erros com as APIs, com os Frameworks e com a plataforma Java, mas não deve ser usado para estruturar uma lógica de negócio, isso deixa o software lento, e caso seja em um servidor, podemos dizer que precisara de muitos mais servidores que o normal para rodar uma aplicação que dispare muitas exceções. O throw também é uma instrução que só deve ser usado pelo desenvolvedor de API. Mencionei acima de criar classes de erros, mas também o desenvolvedor final também não deve criar objetos de erros, e nunca, em hipotenso alguma, jamais, verifique um erro com um try/catch para poder disparar outro erro, isso não tem lógica nenhuma. Você já deve ter visto aquela tradicional stak de erro do Java, aquilo só é possível porque após disparar uma exceção, a máquina virtual fica verificando por todos os lugares que a exceção passou, e por isso que é muito mais lento trabalhar com exceções.

Em Java tem dois tipos de erros, os que estendem de Exception como IOException, SQLException, InterruptedException, erros não verificáveis que sempre devem ser circundados por um try/catch ou o código não vai compilar, esses erros são inerentes a lógica do programa, ou seja, o programa sempre estará sujeito a ter esses erros e por isso deve tratá-los no try/catch.

O outro de tipo de erro são os que estendem de RuntimeException como NumberFormatException, NullPointerException, ClassCastException, ArrayIndexOutOfBoundsException, que são os erros verificáveis, ou seja, pela lógica do programa, você consegue impedir que esses erros ocorram e por isso não é obrigatório usar o try/catch. Se uma aplicação dispara erros verificáveis quer dizer que o software não está bem estruturado, e para muitas empresas, este é um motivo suficiente para mandar um programador embora.

A

Ubarreto21, no seu código contato nunca sera nulo, o que é nulo são as propriedades(nome, email, endereco) deste obejto, seu if é irrelevante estar ali, contato foi inicializado logo acima quando você fez: new Contato(). e também foi inicializado no DAO, o que esta acontecendo é que as propriedades do objeto estão nulas, você poderia testar com vários if’s cada propriedade ou inicializar elas no momento do getString ex: rs.getString(“nome”) != null ? rs.getString(“nome”) : “um valor default” assim nunca seriam nulas poderia ser apenas String vazia, acho que pdoe testar com o .lenth() também if == 0 configura com um valor default.

M

Na verdade não aix, ele pode até ter dado o Contato contato = new Contato(); mas este contato foi criado desnecessariamente, porque na linha abaixo ele coloca contato = dao.pesquisaContatoPorId(2);, logo esta instrução vai descartar o objeto anterior e atribuir um novo objeto, que pode sim ser nulo, ele não colocou o código do pesquisaContatoPorId mas provavelmente esse método faz um SELECT em algum banco de dados e retorna null caso não encontre o id.

A

verdade, não tinha me ligado :slight_smile:

U

Isso mesmo @Murilo.MPO, o pesquisaContatoPorId(2) faz uma busca no banco de dados, se ele encontrar o ID = 2 no banco ele retorna o contato, mas caso não encontre o retorno é null Mas eu vi as dicas que deu ali em cima sobre Try/ Catch. Como eu substituiria esse bloco if que testa se é null por um Try/ Catch?

Criado 18 de março de 2016
Ultima resposta 23 de mar. de 2016
Respostas 5
Participantes 3