[Java] NullPointException
MVC패턴 연습 겸 코드를 짜다가, 드디어 완성!!! 하고 행복한 마음으로 실행 버튼을 눌렀는데
어쩔 수 없죠.. 오류 잡아봅시다
java.lang.NullPointException 라는 놈이 눈에 띕니다.
뭐가 null값이래요 그러니까 음.. 제가 뭔가 반환받거나 출력하고싶은데 그게 값이 없다는 말이겠죠?
디버깅을 해보겠습니다
그럼 이렇게 좌측에 브레이킹포인트 아이콘과 함께 실행이 뚝 멈춘 코드에 하이라이팅이 되어있는 것을 볼 수 있습니다
저기에서 뭔가 값이 들어온게 없다는 것 같네요. 제가 코드를 다 올리지는 않았지만 Controller 클래스에서 저 코드를 받아 출력을 하려했거든요. 그럼 또 뭐가 null값인지 한번 또 봐보자~했더니
PersonModel 클래스형 변수로 선언한, 이 model이라는 친구가 null값이래요
그러니까 제가 값도 안줘놓고서는 "내놔! get해와!" 하고있던 겁니다;;
자바 입장에서는 '없는데 어떻게 내놔요' 했던 거구요
암튼 저의 사고회로를 보여드리기 위해서 View와 Controller 코드를 올려드리자면 아래와 같습니다
public class PersonView {//사람의 정보를 화면에 출력
PersonModel model;
public void startMsg() {
System.out.print("사람 이름을 입력하세요: ");
}
//입력한 이름을 보여주는 메서드
public void showUserInput() {
System.out.println(model.getName());
}
}
import java.util.Scanner;
public class PersonController { //사용자 입력을 처리하는 곳
//Model과 View를 연결하기 위해..
private PersonModel model = new PersonModel();
private PersonView view = new PersonView();
public PersonController (PersonModel model, PersonView view) {
this.model = model;
this.view = view;
}
public void run() {
//이름 받고
Scanner sc = new Scanner(System.in);
view.startMsg();
String name = sc.next();
model.setName(name); //name에 입력받은 이름 저장
System.out.print("사람 이름 : ");
view.showUserInput();
sc.close();
}
}
일단 저의 목적이 뭐였냐면.. 사용자가 입력한 어떤 사람의 이름 'name'을 받아서, 그걸 Model에 저장하고.
그 저장한 값을 View에 구현한 showUserInput()이라는 메서드를 통해서 출력하려 했습니다.
그러니까 View의 showUserInput()메서드에서 출력하려는 model.getName()이 null값인데, Controller의 run() 메서드에서 냅다 그냥 뽑아내라고 view.showUserInput() 을 외쳐대고 있었으니 오류가 나지 않을 수가 없었네요.
그런데 제가 오류를 쉽게 잡아내지 못하던 이유는 사실 또 따로 있습니다.
그래, 너가 null값을 받고있는건 알겠는데.. 난 분명 너에게 name을 받아서 model.setName(name)을 통해 이름도 쥐어주지 않았니? 왜 자꾸 뭐가 없다는거니? 설마 이게 이름을 세팅하지 못하고 있는건가?
.
.
.
하고 이번엔 View의 메서드가 아닌, 저 Controller의 run()메서드에 직접 출력 코드를 집어넣어서 테스트 해봤습니다
public void run() {
//이름 받고
Scanner sc = new Scanner(System.in);
view.startMsg();
String name = sc.next();
model.setName(name); //name에 입력받은 이름 저장
System.out.print("사람 이름 : ");
System.out.println(model.getName());
sc.close();
}
이렇게 System.out.println(model.getName())을 작성해서 실행해보면
(야속하게도) 너무나도 문제없이 의도한대로 잘 돌아가는 모습을 볼 수 있습니다
아무튼 저기에는 전혀 문제가 없다는 것인데, 그럼 도대체 왜 저 showUserInput()만 거치면 애가 갈피를 못잡는 걸까요..?
난 분명 model의 name 셋팅을 잘 해줬는데말이죠
그렇게 무려 6시간 뒤, 저는 엄청난 사실을 깨닫고 맙니다.
Controller에서 선언한 model과, View에서 선언한 model은 완전 다른 놈이잖아?!
진짜 당연한건데! 정말 당연한 사실인데도, 그것도 엄청나게 기초적인...!
이걸 캐치를 못해서 장장 6시간동안 코드 한 줄만 노려보고 있었던거예요
그러니까 계속 name을 Controller에서 선언한 model 객체에 떠먹여줘놓고서는, 엉뚱한 View의 메서드에 달려가서 단지 이름이 같다는 이유 하나만으로 "name줬잖아! name줬잖아! Controller 쟤는 잘 출력하던데 너는 왜 못하니!!!" 이러고 있던거예요 제가
아무튼 그렇게 드디어 잘못된 점을 찾아내고, 마지막으로 고친 두 개의 메서드입니다
public void run() {
//이름 받고
Scanner sc = new Scanner(System.in);
view.startMsg();
String name = sc.next();
model.setName(name); //name에 입력받은 이름 저장
System.out.print("사람 이름 : ");
view.showUserInput(model);
sc.close();
}
public void showUserInput(PersonModel model) { //매개변수 부여해서 값 입력받을 수 있도록 함
System.out.println(model.getName());
}
그리고 실행을 해보면
드디어 원하는 결과가 나옵니다 ^____ㅜ 눈물나네요
매번 내 뜻도 못 알아듣는 멍청한 컴퓨터!라고 염불을 외지만, 사실 마음속으로는 잘 알고있습니다..
사실 멍청한건 나였고, 컴퓨터는 그저 시킨대로 착실히 일 하고 있었을 뿐이라는 것을요...
하지만 인간의 의도를 파악하는 공감지능 장착 개발언어도 언젠가는 나오지 않을까요?
아무튼 오늘의 오류잡기는 여기서 끝..입니다
안녕!