Nuova eccezione Nullpointer in Java 17
Fonte: Dev.to Ogni sviluppatore Java dovrebbe essere a conoscenza dell'esistenza di una nuova eccezione Nullpointer o NPE in Java 17. Questa è una di queste situazioni che dovresti sempre cercare di prevenire. A volte Nullpointer significa che è necessario eseguire il debug del codice per trovare un piccolo bug. Un NPE è un'eccezione di runtime che si verifica quando il codice desidera utilizzare un oggetto o un riferimento a un oggetto che ha un valore null. Può verificarsi se non viene assegnato alcun valore o se l'oggetto non ha un riferimento. Prima dell'ultima versione di OpenJDK (versione 17), una normale eccezione Nullpointer nell'analisi dello stack sarebbe stata simile a questa:java.lang.NullPointerException: null
Naturalmente, questo non è tutto ciò che devi sapere sulle tracce dello stack. Come puoi vedere, non indica dove o perché si è verificata questa eccezione. Guarda come Java 17 affronta questo problema:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
In questo esempio, l'eccezione indica dove e quale è il nostro riferimento all'oggetto null. È così semplice!
Cosa significa <T> in Java?
Fonte: Dev.to <T> è una lettera comune che sta per "Tipo" e si riferisce al concetto generico in Java. Puoi usare un'altra lettera per questo, ma come puoi vedere, la lettera T è preferibile.Cos'è il generico?
Generic è un modo per parametrizzare una classe, un metodo o un'interfaccia. Diamo un'occhiata ad un esempio di generico: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);
}
}
- Abbiamo una classe chiamata House che può accettare un tipo di oggetto arbitrario.
- Successivamente abbiamo un campo chiamato doorNumber , che può anche accettare qualsiasi tipo di oggetto.
- Alla fine dichiariamo un costruttore parametrizzato e stampiamo il numero della porta.
public class GenericsExample {
public static void main(String[] args) {
House<String> mainHouse = new House<>("14a");
mainHouse.print();
}
}
Il risultato sarà simile a questo:
Il tuo numero civico è: 14a
Sostituiremo la lettera “T” con “String” e inseriremo il numero civico nel costruttore. Possiamo utilizzare più tipi se, ad esempio, abbiamo bisogno che una classe accetti più di un oggetto. Possiamo aggiungere un'altra lettera e quindi dire: vogliamo che la classe accetti un altro Generic.
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();
}
}
Il risultato sarà così:
Abiti a: 14 Tellson Avenue
Finora abbiamo visto esempi di utilizzo di Generic a livello di classe. Ma possiamo anche avere metodi e interfacce comuni.
Metodo generico
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);
}
}
Il metodo accetta qualsiasi tipo di oggetto e restituisce il numero della porta, che sarà qualsiasi tipo di Object . In questo caso, vogliamo che il metodo accetti un numero intero. Il risultato sarà:
Abiti al numero civico: 14
Interfaccia generica
Per prima cosa crea l'interfaccia.package Generics;
interface Property<T>{
void hasBalcony(T balcony);
}
Quindi implementare l'interfaccia.
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");
}
}
Risultato:
C'è un balcone nella stanza? SÌ
Quali sono i vantaggi dell’utilizzo dei generici?
- Migliore controllo in fase di compilazione : se usi un tipo di oggetto diverso da quello specificato, il compilatore te lo dirà.
- Riusabilità : puoi utilizzare una classe, un metodo o un'interfaccia più volte perché sei tu a decidere quale tipo di oggetto utilizzare a seconda di ciò che stai cercando di ottenere.
- È ottimo per strutture dati e algoritmi : ArrayList e HashMap sono solo alcuni esempi in cui viene utilizzato Generic.
GO TO FULL VERSION