JavaRush /Blogue Java /Random-PT /Pausa para café #98. Nova exceção Nullpointer em Java 17....

Pausa para café #98. Nova exceção Nullpointer em Java 17. O que significa em Java?

Publicado no grupo Random-PT

Nova exceção Nullpointer em Java 17

Fonte: Dev.to Todo desenvolvedor Java deve saber sobre a existência de uma nova exceção Nullpointer ou NPE em Java 17. Esta é uma situação que você deve sempre tentar prevenir. Às vezes, Nullpointer significa que você precisa depurar seu código para encontrar um pequeno bug. Pausa para café #98.  Nova exceção de Nullpointer em Java 17. O que <T>  em Java?  - 1Um NPE é uma exceção de tempo de execução que ocorre quando seu código deseja usar um objeto ou uma referência a um objeto que possui um valor nulo. Pode ocorrer se nenhum valor for atribuído ou o objeto não tiver uma referência. Antes da versão mais recente do OpenJDK (versão 17), uma exceção Nullpointer normal no rastreamento de pilha seria mais ou menos assim:
java.lang.NullPointerException: null
Claro, isso não é tudo que você precisa saber sobre rastreamentos de pilha. Como você pode ver, não indica onde ou por que essa exceção ocorreu. Veja como o Java 17 lida com esse problema:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
Neste exemplo, a exceção indica onde e qual é a nossa referência de objeto nulo. É simples assim!

O que significa <T> em Java?

Fonte: Dev.to <T> é uma letra comum que significa “Tipo” e se refere ao conceito genérico em Java. Você pode usar outra letra para isso, mas como pode ver, a letra T é preferível. Pausa para café #98.  Nova exceção de Nullpointer em Java 17. O que <T>  em Java?  - 2

O que é genérico?

Genérico é uma forma de parametrizar uma classe, método ou interface. Vejamos um exemplo de genérico:
package Generics;

class House<T>{

    T doorNumber;

    public House(T doorNumber) {
        this.doorNumber = doorNumber;
    }

    public void print(){
        System.out.println("Your house number is: " + this.doorNumber);
    }
}
  • Temos uma classe chamada House que pode aceitar um tipo de objeto arbitrário.
  • A seguir temos um campo chamado doorNumber , que também pode aceitar qualquer tipo de objeto.
  • No final declaramos um construtor parametrizado e imprimimos o número da porta.
Simplificando, o usuário pode decidir se esse número é Inteiro, String, Flutuante e assim por diante. NOTA: você só pode usar Objects . Tipos primitivos não são suportados porque os genéricos devem ser usados ​​em tempo de compilação. Quando usamos Genéricos, T substitui qualquer coisa que possa estender a classe Object , e os primitivos não possuem essa propriedade. Digamos que queremos que doorNumber seja uma string.
public class GenericsExample {
    public static void main(String[] args) {
        House<String> mainHouse = new House<>("14a");
        mainHouse.print();

    }
}
O resultado ficará assim:
O número da sua casa é: 14a
Substituiremos a letra “T” por “String” e inseriremos o número da casa no construtor. Podemos usar vários tipos se, por exemplo, precisarmos que uma classe aceite mais de um objeto. Podemos acrescentar mais uma letra e assim dizer: queremos que a classe aceite outro Genérico.
package Generics;

class House<T, V>{

    T doorNumber;
    V streetName;

    public House(T doorNumber, V streetName) {
        this.doorNumber = doorNumber;
        this.streetName = streetName;
    }

    public void print(){
        System.out.println("You live at: " + this.doorNumber + " " + this.streetName);
    }
}

public class GenericsExample {
    public static void main(String[] args) {
        House<Integer, String> mainHouse = new House<>(14, "Tellson Avenue");
        mainHouse.print();

    }
}
O resultado será assim:
Você mora em: 14 Tellson Avenue
Até agora vimos exemplos de uso de Genérico em nível de classe. Mas também podemos ter métodos e interfaces comuns.

Método genérico

package Generics;

class House{

    public <T> void print(T doorNumber){
        System.out.println("You live at house number: " + doorNumber);
    }

}

public class GenericsExample {
    public static void main(String[] args) {
        House mainHouse = new House();
        mainHouse.<Integer>print(14);

    }
}
O método aceita qualquer tipo de objeto e gera o número da porta, que será qualquer tipo de Object . Neste caso, queremos que o método aceite um número inteiro. O resultado será:
Você mora na casa número: 14

Interface genérica

Primeiro crie a interface.
package Generics;

interface Property<T>{
    void hasBalcony(T balcony);
}
Em seguida, implemente a interface.
package Generics;

public class House implements Property<String> {

    @Override
    public void hasBalcony(String balcony) {
        System.out.println("Is there a balcony in the room? " + balcony);
    }

    public static void main(String[] args) {
        House mainHouse = new House();
        mainHouse.hasBalcony("YES");
    }

}
Resultado:
Há uma varanda no quarto? SIM
Quais são as vantagens de usar genéricos?
  1. Melhor verificação em tempo de compilação : se você usar um tipo de objeto diferente daquele especificado, o compilador informará isso.
  2. Reutilização : você pode usar uma classe, método ou interface várias vezes porque decide qual tipo de objeto usar dependendo do que está tentando alcançar.
  3. É ótimo para estruturas de dados e algoritmos : ArrayList e HashMap são apenas alguns exemplos onde Generic é usado.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION