NullPointerException

HU·2022년 2월 11일
0

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)

java.lang.NullPointerException 몇일째 에러입니다.ㅠ

// conn 연결에 문제가 생겨 초기값 null 값이 유지
pstmt = conn.prepareStatement(sql);

실제 사례(2)

java.lang.NullPointerException 에러 납니다.. ㅜㅜ (에러메세지추가했습니다.)

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 차이점 알아보기

profile
지식 쌓기

0개의 댓글