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. Um 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.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.
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?
- Melhor verificação em tempo de compilação : se você usar um tipo de objeto diferente daquele especificado, o compilador informará isso.
- 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.
- É ótimo para estruturas de dados e algoritmos : ArrayList e HashMap são apenas alguns exemplos onde Generic é usado.
GO TO FULL VERSION