JavaRush /Java Blog /Random EN /Coffee break #98. New Nullpointer exception in Java 17. W...

Coffee break #98. New Nullpointer exception in Java 17. What does mean in Java?

Published in the Random EN group

New Nullpointer exception in Java 17

Source: Dev.to Every Java developer should know about the existence of a new Nullpointer Exception or NPE in Java 17. This is one such situation that you should always try to prevent. Sometimes Nullpointer means you need to debug your code to find a small bug. Coffee break #98.  New Nullpointer Exception in Java 17. What does <T>  in Java?  - 1An NPE is a runtime exception that occurs when your code wants to use an object or a reference to an object that has a null value. It can occur if no value is assigned or the object does not have a reference. Before the latest version of OpenJDK (version 17), a normal Nullpointer exception in the stack trace would look something like this:
java.lang.NullPointerException: null
Of course, that's not all you need to know about stack traces. As you can see, it does not indicate where or why this exception occurred. See how Java 17 deals with this problem:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
In this example, the exception indicates where and what our null object reference is. It's that simple!

What does <T> mean in Java?

Source: Dev.to <T> is a common letter that stands for “Type” and it refers to the Generic concept in Java. You can use another letter for this, but as you can see, the letter T is preferable. Coffee break #98.  New Nullpointer Exception in Java 17. What does <T>  in Java?  - 2

What is Generic?

Generic is a way to parameterize a class, method, or interface. Let's look at an example of a generic:
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);
    }
}
  • We have a class called House that can accept an arbitrary object type.
  • Next we have a field called doorNumber , which can also accept any type of object.
  • At the end we declare a parameterized constructor and print the door number.
Simply put, the user can decide whether this number is Integer, String, Float, and so on. NOTE: you can only use Objects . Primitive types are not supported because generics are intended to be used at compile time. When we use Generics, T replaces anything that can extend the Object class , and primitives don't have this property. Let's say we want doorNumber to be a string.
public class GenericsExample {
    public static void main(String[] args) {
        House<String> mainHouse = new House<>("14a");
        mainHouse.print();

    }
}
The result will look like this:
Your house number is: 14a
We will replace the letter “T” with “String” and enter the house number into the constructor. We can use multiple types if, for example, we need a class to accept more than one object. We can add another letter and thereby say: we want the class to accept another 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();

    }
}
The result will be like this:
You live at: 14 Tellson Avenue
So far we have seen examples of using Generic at the class level. But we can also have common methods and interfaces.

Generic method

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

    }
}
The method accepts any type of object and outputs the door number, which will be any type of Object . In this case, we want the method to accept an integer. The result will be:
You live at house number: 14

Generic interface

First create the interface.
package Generics;

interface Property<T>{
    void hasBalcony(T balcony);
}
Then implement the 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");
    }

}
Result:
Is there a balcony in the room? YES
What are the advantages of using generics?
  1. Better compile-time checking : If you use an object type other than the one you specified, the compiler will tell you so.
  2. Reusability : You can use a class, method, or interface multiple times because you decide which object type to use depending on what you are trying to achieve.
  3. It is great for data structures and algorithms : ArrayList and HashMap are just a few examples where Generic is used.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION