Java 17 中新的空指针异常
来源:Dev.to 每个 Java 开发人员都应该知道 Java 17 中存在新的空指针异常或 NPE。这是您应该始终尽力避免的一种情况。有时空指针意味着您需要调试代码才能找到小错误。 NPE 是一种运行时异常,当您的代码想要使用具有空值的对象或对对象的引用时,就会发生这种异常。如果未分配值或对象没有引用,则可能会发生这种情况。在最新版本的 OpenJDK(版本 17)之前,堆栈跟踪中的正常空指针异常将如下所示:java.lang.NullPointerException: null
当然,这并不是您需要了解的有关堆栈跟踪的全部信息。正如您所看到的,它没有表明此异常发生的位置或原因。看看Java 17是如何处理这个问题的:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)
在此示例中,异常指示我们的空对象引用在哪里以及是什么。就这么简单!
Java中<T>是什么意思?
来源:Dev.to <T>是一个常见的字母,代表“Type”,它指的是 Java 中的 Generic 概念。您可以使用另一个字母,但正如您所看到的,字母 T 更好。什么是通用型?
泛型是一种参数化类、方法或接口的方法。让我们看一个泛型的例子: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);
}
}
- 我们有一个名为House的类,它可以接受任意对象类型。
- 接下来我们有一个名为DoorNumber的字段,它也可以接受任何类型的对象。
- 最后我们声明一个参数化构造函数并打印门号。
public class GenericsExample {
public static void main(String[] args) {
House<String> mainHouse = new House<>("14a");
mainHouse.print();
}
}
结果将如下所示:
您的门牌号码是:14a
我们将字母“T”替换为“String”,并将门牌号输入到构造函数中。例如,如果我们需要一个类来接受多个对象,我们可以使用多种类型。我们可以添加另一个字母,从而表示:我们希望该类接受另一个泛型。
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();
}
}
结果会是这样的:
您住在: 14 Tellson Avenue
到目前为止,我们已经看到了在类级别使用 Generic 的示例。但我们也可以有通用的方法和接口。
通用方法
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);
}
}
该方法接受任何类型的对象并输出门号,该门号可以是任何类型的Object。在本例中,我们希望该方法接受一个整数。结果将是:
您居住的门牌号:14
通用接口
首先创建界面。package Generics;
interface Property<T>{
void hasBalcony(T balcony);
}
然后实现接口。
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");
}
}
结果:
房间里有阳台吗?是的
使用泛型有什么优点?
- 更好的编译时检查:如果您使用指定类型以外的对象类型,编译器会告诉您这一点。
- 可重用性:您可以多次使用一个类、方法或接口,因为您可以根据要实现的目标来决定使用哪种对象类型。
- 它对于数据结构和算法来说非常有用:ArrayList和HashMap只是使用 Generic 的几个例子。
GO TO FULL VERSION