* 39. Reflection API를 사용해서 DAO 객체의 메서드 호출을 자동화하기
기존의 Case 문법으로 사용했던 추가,목록,조회,변경,삭제 등의 명령을 대체한다.
// 데이터 이름과 메서드 이름 알아내기
String[] values = command.split("/");
String dataName = values[0];
String methodName = values[1];
// 데이터 이름으로 DAO 객체를 꺼낸다.
Object dao = daoMap.get(dataName);
if (dao == null) { // 만약 데이터를 처리 할 DAO를 찾지 못한다면 오류 정보를 클라이언트에게 보낸다.
out.writeUTF(
new ResponseEntity().status(ResponseEntity.ERROR).result("데이터를 찾을 수 없습니다.").toJson());
continue;
}
// Dao객체에서 메서드 찾기
Method method = findMethod(dao, methodName);
if (method == null) {
// 만약 클라이언트가 요청한 메서드를 찾지 못한다면 오류 정보를 클라이언트에게 보낸다.
out.writeUTF(
new ResponseEntity().status(ResponseEntity.ERROR).result("메서드를 찾을 수 없습니다.").toJson());
continue;
}
// DAO 메서드 호출하기
Object result = call(dao, method, request);
// 메서드 호출 결과를 클라이언트에게 보낸다.
ResponseEntity response = new ResponseEntity();
response.status(ResponseEntity.SUCCESS);
response.result(result);
out.writeUTF(response.toJson());
}
public static Method findMethod(Object obj, String methodName) {
// DAO에 해당 메서드가 있는지 알아낸다.
Method[] methods = obj.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
return methods[i];
}
}
return null;
}
public static Object call(Object obj, Method method, RequestEntity request) throws Exception {
Parameter[] params = method.getParameters();
if (params.length > 0) {
Object arg = request.getObject(params[0].getType());
return method.invoke(obj, request.getObject(params[0].getType()));
} else {
return method.invoke(obj);
}
* 예외처리 문법 - 오류가 발생해도 JVM 실행을 멈추지 않게 하는 문법
* 예외 정보를 담는 크래스의 hierarchy (계층도)
Error
스택오버플로우와 같이 복구할 수 없는 것이다.
* 개발자가 사용하면 안된다 !
Exception ?
예외는 복구가 가능하며
적절한 조치 후에 계속 실행 가능한 에러이다.
checked 예외와 unchecked 예외가 존재한다.
Exception은 checked 체크 예외이며 에러처리 코드를
명시적으로 작성했는지 컴파일러가 검사한다.
Runtime Exception 은 언체크 예외이며
예외처리 코드를 작성했는지 컴파일러가 검사하지 않는다.
* Exception 예외 다루기
예외 타입이 어떤 것인지 반드시 예외정보 타입을 선언해야한다.
throws Throwable
메인에서 test를 실행하고 test에서 m를 실행하는데
m이 던진 예외를 test가 받을 수 없기 때문에 상위 호출자인
main에서 이 예외를 catch 하여 print문을 출력한 것이다.
모든 상위 호출자가 예외를 전달받지 못하고 JVM이 전달받게 된다면
예외가 발생한 메서드를 호출하기 까지의 모든 과정을 상세 출력한다.
그리고, JVM은 종료된다 !
RuntimeExcepiton 예외는 unchecked Exception 이기 때문에
메서드 선언부에 표시를 해주지 않아도 된다 !
아래 예제에서 선언을 해주는 것과 안해준 것의 차이가 없다 !
예제)
그러나 Checked Exception 의 하위 예외는 모두 메서드 선언부에
명시해주어야 한다. 컴파일러 이를 검사하기 때문이다.
예제)
또는 수퍼클래스인 Exception 을 명시하여 모든 메서드에 선언하지 않아도
되게 만들 수 있다. 하지만, 이것은 어떤 예외인지 알 수 없어 유지보수에 좋지 않다.
예제)
가장 정석적인 모범답안 !
아래에 순서대로 에서 예외가 발생하는 순서대로 메서드에 선언해준다.
그리고 catch로 예외 해당하는 오류가 발생하면 print문으로 어떤 예외인지를
사용자에게 알려준다 !
예제)
Exception e 는
throw new Exception()
throw new RuntimeException()
throw new IOException()
throw new SQLException()
를 포함하는 에러이다.
단, throw new Error() 은 포함하지 않는다 .
scanner 같은 자원은 다른 프로그램에서 사용할 수 있게
반드시 사용 후에는 실행을 종료해주어야한다.
그런데, 오류(예외)가 발생하면 scanner를 close()를 하지 못한다.
그래서 반드시 실행되는 finally에서 close() 를 통해 자원을 해제해주어야 한다.
예제)
다른 방법으로는 try-with-resources 문법을 사용할 수 있다.
try 블럭 안에서 객체를 선언함으로써 그 객체가 실행되는 클래스의 자원을
자동으로 정리되게 할 수 있다.
예제)