문제상황
기본적으로 JVM이 .java 파일을 .class 파일로 컴파일하는 과정에서 메서드의 파라미터 이름을 arg로 수정합니다.
예시: sayNameAndAge(String name, String age)
→ sayNameAndAge(String arg0, String arg1)
일반적인 프로그래밍에서는 컴파일을 할 때, 메서드 파라미터의 이름이 arg로 대체된다는 것을 알 기회가 없기에 많이 당황스러웠습니다. 이렇게 하면 매개변수를 어떻게 매칭시키지? 라는 생각이 들었습니다.
해결방법
처음 들었던 생각은 컴파일 과정에서 매개변수명을 남겨야한다는 생각이었습니다.
다행히 컴파일 옵션에서 파라미터 명을 유지할 수 있는 옵션이 있고, 저는 Gradle로 환경을 구성해서 build.gradle 파일을 수정해서 간단하게 해결했습니다.
compileJava {
options.compilerArgs << '-parameters'
}
추가적인 문제
하지만 다른 문제가 있는데 제가 개발하고 있는 것은 프레임워크이고 다른 개발자의 컴파일 옵션을 강제할 수 없다는 것이었습니다.
추가적인 문제 해결방법
해결방법을 고민하다가 Spring Application을 개발할때 어떻게 했는지 다시 생각해보니, @PathVariable, @RequestParam등에 변수명이 존재함을 눈치챘습니다. Spring Framework 개발자들도 같은 고민끝에 어노테이션에 변수명을 넣어야한다고 결론을 내린것이죠.
그래서 컨트롤러 핸들러 메서드를 실행하고 매개변수를 매칭시킬때 해당 변수를 통해 매칭시키는 것으로 구현했습니다.
if (parameter.isAnnotationPresent(PathVariable.class)) {
PathVariable pathVariable = parameter.getDeclaredAnnotation(PathVariable.class);
String parameterName = pathVariable.value();
Object value = objectMapper.readValue(pathVariables.get(parameterName), parameter.getType());
args[i] = value;
} else if (parameter.isAnnotationPresent(RequestBody.class)) {
args[i] = objectMapper.readValue(requestBody, parameter.getType());
} else if (parameter.isAnnotationPresent(RequestParam.class)) {
RequestParam requestParam = parameter.getDeclaredAnnotation(RequestParam.class);
String parameterName = requestParam.value();
Object value = objectMapper.readValue(queryParams.get(parameterName), parameter.getType());
args[i] = value;
}
출처:
https://medium.com/@daclouds/java-method-arguments-parameters-name-7c6ba6622e37
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html