NullPointerException
발생 원인: 사용할 개체의 인스턴스를 생성하지 않은 상태에서 참조할 경우 발생한다. (존재하지 않는 주소를 가리키려하므로.)
해결 방법: 방어 코드를 작성하는 것이 적절하다.
1. try ~ catch 구문을 사용하여 예외 처리를 하고 null 인지 확인하는 코드를 작성한다.
2. 의미 없는 null 값은 파라미터로 넘기지 않도록 한다.
NPE 발생 시나리오 및 예방하는 방법(1)
*NPE: NullPointerException
예시 1.
public class NullPointerExceptionTest {
String nullValue = null;
@Test
public void testCase() {
// 에러 발생
/*
* if ( this.nullValue.equals("1") ) {
* System.out.println("1과 같다.");
* }
*/
// 수정
if ( "1".equals(this.nullValue) ) {
System.out.println("1과 같다.");
}
}
}
예시 2.
public class NullPointerExceptionTest {
String nullValue = null;
@Test
public void testCase() {
// 에러 발생
// System.out.println(this.nullValue.toString());
// (1)
System.out.println(this.nullValue);
// (2) this.nullValue가 String 타입이 아니었다면
System.out.println(String.valueOf(this.nullValue);
// (3)
try {
System.out.println(this.nullValue.toString());
} catch ( NullPointerException npe ) {
System.out.println("Null Point Exception");
}
// 비교 대상인 null 값은 고정이고,
this.nullValue는 값이 무엇인지 확인해야 하므로 우측에 위치시킨다.
참고 사이트
[JAVA] NullPointerException 원인과 예방법
NPE 발생 시나리오 및 예방하는 방법(2)
1. Null 객체의 메소드를 참조
class Init {
public static Init call() {
// null 값인 오브젝트를 반환한다.
return null;
}
public void print(final String s) {
System.out.println(s.toLowerCase());
}
}
public class TestClass {
public static void main(final String[] args) {
// Init 클래스의 변수를 만든다.
Init init = Init.call();
// null 값인 오브젝트의 메소드를 부른다.
init.print("Hello, World!");
}
}
NPE 발생 시점: init.print("Hello, World!");
2. Null 객체의 필드에 접근
class MyClass {
int numField = 100;
public static MyClass initT() {
// method returns a null object
return null;
}
public void print(final String s) {
System.out.println(s.toLowerCase());
}
}
public class Main {
public static void main(final String[] args) {
MyClass t = MyClass.initT();
int num = t.numField;
System.out.println(num);
}
}
NPE 발생 시점: int num = t.numField;
3. Null 인자를 전달
public class Main {
public static void print_LowerCase(final String s) {
System.out.println(s.toLowerCase());
}
public static void main(final String[] args) {
print_LowerCase(null);
}
}
NPE 발생 시점: System.out.println(s.toLowerCase());
4. Null 배열 참조
// 첫 번째 경우
public class Main {
public static void main(final String[] args) {
int[] dataArray = null;
System.out.println("배열의 길이: " + dataArray.length);
}
}
// 두 번째 경우
public class Main {
public static void main(final String[] args) {
int[] dataArray = null;
System.out.println("Value at index 2:" + dataArray[2]);
}
}
NPE 발생 시점:
첫 번째: System.out.println("Array Length: " + dataArray.length);
두 번째: System.out.println("Value at index 2:" + dataArray[2]);
참고 사이트
Java에서 NullPointerException이란 무엇이며 그것을 피하는 방법
실제 사례(1)
// conn 연결에 문제가 생겨 초기값 null 값이 유지
pstmt = conn.prepareStatement(sql);
실제 사례(2)
if (cos == "eng") {
query = "SELECT name, eng, math FROM score where eng > "+score;
}
else if (cos == "math") {
query = "SELECT name, eng, math FROM score where math > "+score;
}
소스 복붙해서 dbtest.java:69 번째 줄 확인했을 때 엉뚱한 곳으로 확인되어서 댓글을 참고했습니다.
조건문에서 비교 시
'=='은 객체 값의 주소를 비교, 'equals'는 문자열을 비교하는 것이므로
'=='으로 인해 조건문이 안 걸리고 빠져나와 초기값 null이 유지되어 Exception이 발생한 것으로 확인됩니다.
// null 값을 보냈으므로 rs 값에도 null 상태
rs = stmt.executeQuery(query);
.
.
.
// null 값인 rs를 참조하므로 NullPointerException 발생
name[index] = rs.getString("name");
실제 사례(3)
java.lang.NullPointerException error while executing SQL query inside try catch block
문제의 코드
String query = "insert into regcustomers (Name, Email, Address, City, State, Country, Username, Password) values("+"'"+name+"'"+","+"'"+email+"'"+","+"'"+line1+"'"+","+"'"+city+"'"+","+"'"+state+"'"+","+"'"+country+"'"+","+"'"+userid+"'"+","+"'"+password+"'"+");";
try {
rs = st.executeQuery(query);
System.out.println(rs.getRow());
} catch (SQLException e) {
e.printStackTrace();
}
원인: insert 쿼리 사용 시 executeQuery가 아닌 executeUpdate 함수를 사용해야 했습니다.
잘못된 함수의 사용으로 rs에는 null 값이 유지되고, catch 문에서 다른 처리가 없으므로 rs.getRow() 시 NPE 에러가 발생한 것으로 보입니다.
executeQuery:
1. 수행 결과로 ResultSet 객체의 값을 반환한다.
2. SELECT 구문 수행 시 사용되는 함수
[JAVA] Execute, ExecuteQuery, ExecuteUpdate 차이점 알아보기