Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Problemas com NullPointer

Gostei muito do curso. Muito bom mesmo!

Mas fiquei com uma dúvida no que diz respeito ao Java 8:

Sempre me disseram que escrever "código encadeado" metodo().chamadoDentroDeMetodo().comOutraChamada().eMaisOutra()... tornava o código difícil de compreender e carregava um problema que era quando algum dos métodos retorna null, é difícil saber qual foi este método, o que complica o debug de um código.

A meu ver a legibilidade obtida com lambda se utiliza muito deste recurso (como nos exemplos dos streams).

Esta informação que tinha até então é incorreta, ultrapassada ou este é um preço que foi considerado baixo a se pagar pela legibilidade?

Muito grato pela atenção!

2 respostas
solução!

Olá Clayton! A informação que você possui está correta, código encadeado não é uma boa prática. No entanto você comparar o Lambda a um código encadeado é meio errôneo. Quando utilizamos código encadeado dependemos de cada método para chamar o próximo porque trabalhamos com os retornos dos métodos. A exemplo vou utilizar o que você falou:

Ao chamarmos o método metodo() ele nos retorna um objeto, a partir desse objeto nós chamamos o segundo método, chamadoDentroDeMetodo(), assim esse método também retorna um objeto e a partir desse objeto você chama outro método e ai sucessivamente.

Então quando tomamos um NullPointerException em um código encadeado temos que verificar onde é o Null, pois pode vir de qualquer retorno.

Já quando utilizamos Lambda, utilizamos um objeto pra chamarmos um método e outros métodos estão dentro desse método. Seria como se fosse da seguinte forma:

public void metodo(){
    chamadoDentroDeMetodo();
}

Logo, apenas um objeto é utilizado então o NullPointerException apenas poderá dar nele, ou em algum parâmetro que o método utilizar. Para ficar mais claro, veja esse exemplo:

palavras.forEach(new Consumer<String>() {
            public void accept(String s) {
                System.out.println(s);
            }
        });

O lambda ficaria da seguinte forma:

palavras.forEach((String s) -> {
                System.out.println(s);
        });

Veja o que acontece, o método forEach() pede como parâmetro um Consumer, então nos Instanciamos esse consumer, chamamos o método accept dele e dentro do método accept nós imprimimos a String como parâmetro, ou seja chamamos o método System.out.println(s); Mas veja que dentro do método accepts nós chamamos o System.out.println(s). Ou seja em caso de NullPointerException nós só poderiamos pensar em ou ser no System.out.println(s);ou logo no ínicio no forEach(), pois são os únicos métodos que utilizam objeto, o forEach utiliza o Consumer e o System.out.println(s) a String. Enquanto que no código encadeado pensaríamos em todos, pois todos nos retornam um objeto. O lambda é apenas uma forma mais simplificada de ter que escrever código desnecesário. Veja que na forma normal temos que escrever o método accept(), mas a unica utilidade dele é chamar o System.out.println(s) então é desnecessário escrever ele, o mais importante é o System.out.println(s).

Espero ter ajudado! Bons estudos!

Tem razão Romário,a minha duvida era especificamente sobre o exemplo dado na questão do uso do Stream. Depois que respondeu voltei ao curso e vi que formulei mal minha pergunta. Me desculpem. A duvida na verdade eh a mesma que mandei no post anterior,mas nao sobre lambda e sim sobre o uso feito no exemplo do stream no video da aula.