1. 특징

    1. null을 참조하려고 할 때 발생함
    String s = null;
    System.out.println(s.length()); //여기서 NPE(NullPointerException)
    
  2. 대표적인 상황

    1. 메서드 호출

      obj.method(); //obj가 null이면 NPE
      
    2. 맴버 변수 접근

      obj.field; // obj가 null이면 NPE
      
    3. 배열

      int [] arr = null
      int len =arr.length; //NPE
      
    4. 언박싱

      integer num = null;
      int n = num; //null을 int로 바꾸려다 NPE
      
    5. 장점

      1. 문제가 터진 위치를 명확히 알려준다.(하지만 그택 트레이스가 주는 건 문제가 터진 시점이다. 어떤 중 어떤 메서드에서 null을 건드렸는지 정확히 찍어주지만 → null이 거기까지 어떻게 흘러왔는지는 스택트레이스로 알수 없다. 즉, 사고 현장은 분명히 찍히는데, 범인이 왜 거기까지 왔는지 수사하는 건 별개 )
    6. 단점

      1. 런타임에서야 알수 있다.
        1. 컴파일러가 잡아주지 않음
      2. 코드 안정성 떨어짐
        1. 예외 처리를 안하면 프로그램이 죽어버림
      3. 원인 추적이 번거로움
        1. 특히 객체가 여러 계층으로 흘러다니다가 null이 되는 경우
    7. 이러한 예외를 피하는 습관

      1. 초기화 습관을 들이기

        String s="";
        List<String> list = new ArrayList<>();
        
      2. Optional 활용

        Optional<String> opt = Optional.ofNullable(s);
        opt.ifPresent(val -> System.out.println(val.length()));
        
      3. 명확한 null 체크

        if(obj !=null){
        	obj.doSomething();
        }
        
      4. @NonNull, @Nullable 어노테이션으로 IDE 경고 활용

      5. 예시

        public class NpeExample{
        	public static void main(String[] args){
        		String name = null;
        		
        		try{
        			System.out.println(name.toUpperCase()); //여기스 NPE
        		} catch (NullPointerException){
        			System.out.println("널 참조 발생:" + e.getMessage());
        			e.printStackTrace();
        		}
        	
        	}
        }