Java 17의 새로운 Nullpointer 예외
출처: Dev.to 모든 Java 개발자는 Java 17에 새로운 Nullpointer 예외 또는 NPE가 존재한다는 사실을 알아야 합니다. 이는 항상 예방하려고 노력해야 하는 상황 중 하나입니다. 때때로 Nullpointer는 작은 버그를 찾기 위해 코드를 디버그해야 함을 의미합니다. NPE는 코드에서 null 값이 있는 개체 또는 개체에 대한 참조를 사용하려고 할 때 발생하는 런타임 예외입니다. 값이 할당되지 않거나 개체에 참조가 없는 경우 발생할 수 있습니다. 최신 버전의 OpenJDK(버전 17) 이전에는 스택 추적의 일반적인 Nullpointer 예외는 다음과 같았습니다.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)
이 예에서 예외는 null 개체 참조가 어디에 있고 무엇인지 나타냅니다. 그것은 간단합니다!
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"으로 바꾸고 집 번호를 생성자에 입력합니다. 예를 들어, 둘 이상의 개체를 허용하는 클래스가 필요한 경우 여러 유형을 사용할 수 있습니다. 우리는 또 다른 문자를 추가하여 이렇게 말할 수 있습니다: 우리는 수업이 또 다른 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();
}
}
결과는 다음과 같습니다:
귀하의 거주지: 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