JavaRush /Java-Blog /Random-DE /Kaffeepause Nr. 98. Neue Nullpointer-Ausnahme in Java 17....

Kaffeepause Nr. 98. Neue Nullpointer-Ausnahme in Java 17. Was bedeutet in Java?

Veröffentlicht in der Gruppe Random-DE

Neue Nullpointer-Ausnahme in Java 17

Quelle: Dev.to Jeder Java-Entwickler sollte über die Existenz einer neuen Nullpointer-Ausnahme oder NPE in Java 17 Bescheid wissen. Dies ist eine solche Situation, die Sie immer verhindern sollten. Manchmal bedeutet Nullpointer, dass Sie Ihren Code debuggen müssen, um einen kleinen Fehler zu finden. Kaffeepause Nr. 98.  Neue Nullpointer-Ausnahme in Java 17. Was bedeutet <T>  in Java?  - 1Eine NPE ist eine Laufzeitausnahme, die auftritt, wenn Ihr Code ein Objekt oder einen Verweis auf ein Objekt verwenden möchte, das einen Nullwert hat. Dies kann auftreten, wenn kein Wert zugewiesen ist oder das Objekt keine Referenz hat. Vor der neuesten Version von OpenJDK (Version 17) sah eine normale Nullpointer-Ausnahme im Stack-Trace etwa so aus:
java.lang.NullPointerException: null
Das ist natürlich nicht alles, was Sie über Stack-Traces wissen müssen. Wie Sie sehen, gibt es keinen Hinweis darauf, wo oder warum diese Ausnahme aufgetreten ist. Sehen Sie, wie Java 17 mit diesem Problem umgeht:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
In diesem Beispiel gibt die Ausnahme an, wo und was unsere Nullobjektreferenz ist. So einfach ist das!

Was bedeutet <T> in Java?

Quelle: Dev.to <T> ist ein gebräuchlicher Buchstabe, der für „Typ“ steht und sich auf das generische Konzept in Java bezieht. Sie können hierfür einen anderen Buchstaben verwenden, aber wie Sie sehen, ist der Buchstabe T vorzuziehen. Kaffeepause Nr. 98.  Neue Nullpointer-Ausnahme in Java 17. Was bedeutet <T>  in Java?  - 2

Was ist generisch?

Generisch ist eine Möglichkeit, eine Klasse, Methode oder Schnittstelle zu parametrisieren. Schauen wir uns ein Beispiel für ein Generikum an:
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);
    }
}
  • Wir haben eine Klasse namens House , die einen beliebigen Objekttyp akzeptieren kann.
  • Als nächstes haben wir ein Feld namens doorNumber , das auch jede Art von Objekt akzeptieren kann.
  • Am Ende deklarieren wir einen parametrisierten Konstruktor und geben die Türnummer aus.
Einfach ausgedrückt kann der Benutzer entscheiden, ob es sich bei dieser Zahl um eine Ganzzahl, einen String, eine Gleitkommazahl usw. handelt. HINWEIS: Sie können nur Objekte verwenden . Primitive Typen werden nicht unterstützt, da generische Typen zur Kompilierungszeit verwendet werden sollen. Wenn wir Generics verwenden, ersetzt T alles, was die Object- Klasse erweitern kann , und Grundelemente verfügen nicht über diese Eigenschaft. Nehmen wir an, wir möchten, dass doorNumber eine Zeichenfolge ist.
public class GenericsExample {
    public static void main(String[] args) {
        House<String> mainHouse = new House<>("14a");
        mainHouse.print();

    }
}
Das Ergebnis wird so aussehen:
Ihre Hausnummer ist: 14a
Wir ersetzen den Buchstaben „T“ durch „String“ und geben die Hausnummer in den Konstruktor ein. Wir können mehrere Typen verwenden, wenn wir beispielsweise eine Klasse benötigen, die mehr als ein Objekt akzeptiert. Wir können einen weiteren Buchstaben hinzufügen und damit sagen: Wir möchten, dass die Klasse ein anderes Generic akzeptiert.
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();

    }
}
Das Ergebnis wird so aussehen:
Sie wohnen in: 14 Tellson Avenue
Bisher haben wir Beispiele für die Verwendung von Generic auf Klassenebene gesehen. Wir können aber auch gemeinsame Methoden und Schnittstellen haben.

Generische Methode

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);

    }
}
Die Methode akzeptiert jeden Objekttyp und gibt die Türnummer aus, bei der es sich um einen beliebigen Objekttyp handeln kann . In diesem Fall möchten wir, dass die Methode eine Ganzzahl akzeptiert. Das Ergebnis wird sein:
Sie wohnen unter der Hausnummer: 14

Generische Schnittstelle

Erstellen Sie zunächst die Schnittstelle.
package Generics;

interface Property<T>{
    void hasBalcony(T balcony);
}
Anschließend implementieren Sie die Schnittstelle.
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");
    }

}
Ergebnis:
Gibt es einen Balkon im Zimmer? JA
Welche Vorteile bietet der Einsatz von Generika?
  1. Bessere Überprüfung zur Kompilierungszeit : Wenn Sie einen anderen als den von Ihnen angegebenen Objekttyp verwenden, wird Ihnen der Compiler dies mitteilen.
  2. Wiederverwendbarkeit : Sie können eine Klasse, Methode oder Schnittstelle mehrmals verwenden, da Sie abhängig davon, was Sie erreichen möchten, entscheiden, welchen Objekttyp Sie verwenden möchten.
  3. Es eignet sich hervorragend für Datenstrukturen und Algorithmen : ArrayList und HashMap sind nur einige Beispiele, bei denen Generic verwendet wird.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION