logo

Java의 널 포인터 예외

이번 튜토리얼에서는 Java의 Null 포인터 예외에 대해 알아보겠습니다. 널 포인터 예외는 런타임 예외입니다. Null은 개체 참조에 할당할 수 있는 특별한 종류의 값입니다. Null 값이 있는 참조를 사용하려고 할 때마다 NullPointerException이 발생합니다.

Null 포인터 예외에 대한 다양한 시나리오

NullPointerException이 발생할 수 있는 다음 시나리오 중 일부를 살펴보세요.

  • 마치 요소의 배열인 것처럼 Null의 크기나 길이를 계산합니다.

파일 이름: ThrowNullExcep.java

 public class ThrowNullExcep { // main method public static void main(String args[]) { int arr[] = null; // array is assigned a null value System.out.println('The length of the array arr is: ' + arr.length); } } 

산출:

스레드 'main'의 예외 java.lang.NullPointerException: ThrowNullExcep.main(ThrowNullExcep.java:7)에서 ''가 널이므로 배열 길이를 읽을 수 없습니다.
  • Null 값이 있는 개체를 사용하여 메서드를 호출합니다.

파일 이름: ThrowNullExcep1.java

부분 의존성
 public class ThrowNullExcep1 { public void foo() { System.out.println('In the method foo.'); } public static void main(String args[]) { ThrowNullExcep1 obj = null; // assigning null value // invoking the method foo() obj.foo(); } } 

산출:

 Exception in thread 'main' java.lang.NullPointerException: Cannot invoke 'ThrowNullExcep1.foo()' because '' is null at ThrowNullExcep1.main(ThrowNullExcep1.java:13) 
  • NULL 개체에 대해 동기화를 시도하는 경우.

파일 이름: ThrowNullExcep2.java

 // A Java program that synchronizes over a NULL object. import java.util.*; import java.io.*; // A Class that is required for sending the message class Sendr { public void sendMethod(String mssg) { System.out.println('Sending message: ' + mssg ); try { Thread.sleep(100); } catch (Exception exp) { System.out.println('Thread interrupted.' + exp); } System.out.println('
' + mssg + ' is sent'); } } // A Class that is used to send messages with the help of threads Threads class ThreadSend extends Thread { private String mssg; Sendr sendr; // Received a messge obj and the string // mssge that has to be sent ThreadSend(String mStr, Sendr obj) { mssg = mStr; sendr = obj; } public void run() { // Only a single thread is allowed to send a message // at a time. synchronized(sendr) { // synchronizing the send object sendr.sendMethod(mssg); } } } // Driver class public class ThrowNullExcep2 { // main method public static void main(String args[]) { Sendr sendObj = null; ThreadSend Sth1 = new ThreadSend( ' Hello ' , sendObj ); ThreadSend Sth2 = new ThreadSend( ' Bye Bye ' , sendObj ); // Starting the two threads of the ThreadedSend type Sth1.start(); Sth2.start(); // waiting for the threads to end try { Sth1.join(); Sth2.join(); } catch(Exception exp) { System.out.println('Interrupted : ' + exp); } } } 

산출:

 Exception in thread 'Thread-0' Exception in thread 'Thread-1' java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) 
  • 값을 던지는 대신 Null이 발생합니다.

파일 이름: ThrowNullExcep3.java

 // Modifying or accessing the fields of the Null object. public class ThrowExcep3 { int a; // main method public static void main(String args[]) { // assigning a null value ThrowExcep3 obj = null; obj.a = 3; } } 

산출:

 Exception in thread 'main' java.lang.NullPointerException: Cannot assign field 'a' because '' is null at ThrowExcep3.main(ThrowExcep3.java:10) 

NULL 값 요구 사항

null은 Java에서 사용되는 특수 값입니다. 일반적으로 참조 변수에 할당되는 값이 없음을 표시하는 데 사용됩니다. null 값은 연결리스트나 트리 등의 데이터 구조 구현에 주로 사용됩니다. 싱글턴 패턴에서도 사용됩니다.

자바에서 업데이트하는 방법

NullPointerException 방지

NullPointerException을 방지하려면 모든 개체를 사용하기 전에 모든 개체의 초기화가 올바르게 수행되었는지 확인해야 합니다. 참조 변수를 선언할 때 참조 값을 사용하여 필드나 메서드에 액세스하기 전에 null 값이 참조에 할당되지 않았는지 확인해야 합니다.

솔루션과 관련하여 다음과 같은 일반적인 문제를 관찰하십시오.

사례 1: 문자열과 리터럴 비교

일반적인 문제 중 하나는 리터럴과 문자열 변수를 비교하는 것입니다. 리터럴은 Enum 또는 String의 요소일 수 있습니다. null 개체에서 메서드를 호출하는 대신 리터럴을 사용하여 호출하는 것이 좋습니다.

파일 이름: NullPntrExcption.java

 import java.io.*; public class NullPntrExcption { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // The following line of code will raise the NullPointerException // It is because the pntr is null if (pntr.equals('JTP')) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

산출:

.다음 자바
 NullPointerException has been caught. 

이제 이를 피할 수 있는 방법을 살펴보겠습니다.

파일 이름: NullPntrExcption1.java

 public class NullPntrExcption1 { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // Now, the following line of code will not raise the NullPointerException // It is because the string literal is invoking the equals() method if ('JTP'.equals(pntr)) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

산출:

 NullPointerException has been caught. 

사례 2: 메서드 인수를 주시하세요

먼저 메서드 인수에서 null 값을 확인한 다음 메서드 실행을 진행해야 합니다. 그렇지 않으면 IllegalArgumentException이 발생하고 전달된 인수가 잘못되었음을 호출 메서드에 알릴 가능성이 높습니다.

파일 이름: NullPntrExcption2.java

 // A program for demonstrating that one must // check the parameters are null or not before // using them. import java.io.*; public class NullPntrExcption2 { public static void main (String[] args) { // String st is an empty string and invoking method getLength() String st = ''; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // String s set to a value and invoking method getLength() st = 'JTP'; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // Setting st with a value null and invoking method getLength() st = null; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught. ' + exp); } } // method taht computes the length of a string st. // It throws and IllegalArgumentException, if st is null public static int getLength(String st) { if (st == null) { throw new IllegalArgumentException('The argument can never be null.'); } return st.length(); } } 

산출:

자바 더블을 문자열로
 0 3 IllegalArgumentException has been caught. java.lang.IllegalArgumentException: The argument can never be null. 

사례 3: 삼항 연산자 사용

NullPointerException을 피하기 위해 삼항 연산자를 사용할 수도 있습니다. 삼항에서는 부울 표현식이 먼저 평가됩니다. 표현식이 true로 평가되면 val1이 반환됩니다. 그렇지 않으면 val2가 반환됩니다.

파일 이름: NullPntrExcption3.java

 // A program for demonstrating the fact that // NullPointerException can be avoided using the ternary operator. import java.io.*; public class NullPntrExcption3 { // main method public static void main (String[] args) { // Initializing String variable with null value String st = null; String mssge = (st == null) ? 'String is Null.' : st.substring(0, 5); System.out.println(mssge); // Initializing the String variable with string literal st = 'javaTpoint'; mssge = (st == null) ? '' : st.substring(0, 10); System.out.println(mssge); } } 

산출:

 String is Null. javaTpoint