[JAVA] String 을 String… 으로 수정했을 뿐인데 No Such Method 발생
자바에서 String 을 String… 으로 고쳐서 코딩하고, 패치를 마쳤는데 No Such Method 에러 발생.
지금 적어두지 않으면 잊어버릴 것 같아 써둠.
결론을 요약하면, String형의 매개변수를 String… 형으로 변경하였을 때,
해당 메서드를 call하는 클래스 모두를 재컴파일하고, 다시 패치해줘야 한다.
자세한 상황은 다음과 같다.
A.java 에 doSomething 이라는 메서드가 있었는데, 이 메서드는 4개의 매개변수가 필요한 메서드였다.
이를테면 다음과 같은 식이다.
public String doSomething(Object a, Object b, Object c, String d) {
return “temp”;
}
이 메서드를 B.java, C.java, D.java 에서 잘 갖다쓰고 있었고, 개발서버에서도 문제없이 작동되었다.
그러다 마지막 String 매개변수를 여러 개 넘겨주고 싶은 상황이 왔다. 이 부분을 Z.java 라고 하자.
Z.java 에서는 doSomething(obj1, obj2, obj3, “text1”, “text2”); 방식으로 쓰고 싶은 순간이 온 것이다.
유사시에는 doSomething(obj1, obj2, obj3, “text1”, “text2”, “text3”); 식으로 스트링을 3개든 4개든 늘릴 수 있으면 좋겠다고 판단했다.
이 경우 doSomething 메서드의 마지막 매개변수를 Vector나 ArrayList로 바꾸든가, String 배열(String[])로 바꿔 주면 된다.
나는 여기서 String 형을 String… 형으로 바꿨다.
B.java, C.java, D.java 의 코드는 전혀 고치지 않았다.
자바에서는 알다시피 매개변수를 String… 으로 바꾸면 String을 몇 개를 넘겨주든 String 배열로 받는다.
따라서 public String doSomething(Object a, Object b, Object c, String d) 부분을
public String doSomething(Object a, Object b, Object c, String… d) 코드로 변경했으며,
기존에 해당 메서드를 사용하고 있었던 B.java, C.java, D.java 의 코드를 변경할 필요가 없었다.
그냥 Z.java 에서만 스트링을 여러개 붙여서 해당 메서드를 콜했고, 로컬에서는 이상 없이 동작했다.
코드를 직접 변경한 클래스 2개,
즉 A.class(doSomething 메서드가 존재하는 클래스) 와 Z.class(스트링 n개로 doSomething 메서드를 call하는 클래스) 만 패치했다.
그 결과 기존 B.class, C.class, D.class 부분에서 No Such Method 에러가 나는 것이 아닌가.
처음엔 로컬과 개발서버의 자바 버전 차이인 줄 알고(String… 형을 지원하지 않는 버전인가 싶었다) 점검했지만 그게 아니었다.
메서드의 매개변수를 String 형에서 String… 형으로 바꿨다면,
기존에 해당 메서드를 call 하는 모든 클래스를 재컴파일 및 패치해야 하는 것이다.
개발하는 입장에서는 변경된 것이 없었다고 생각했지만,
알고보니 로컬 테스트에서는 이클립스가 B.java, C.java, D.java 에 대해서 자동으로 재컴파일 해줘서, 오류가 발생하지 않았다.
오버로딩과는 동작원리가 다르다.
만약 String 배열을 쓰는 메서드를 하나 더 만들었다면(오버로딩이었다면), B.class, C.class, D.class 를 재컴파일할 이유는 없다.
오버로딩은 불리는 쪽(Callee)에서 메서드를 여러 개 제공하는 것이다.
하지만 String…형은 부르는 쪽(Caller)에서 컴파일 과정에서 메서드에 맞는 자바 바이트 코드를 생성해내는 것으로 보인다.
String… 형을 사용한 부분인 A.class 는 해당 매개변수를 무조건 배열로만 받고,
B.class, C.class, D.class 쪽에서 스트링 1개를 배열에 담아 call하는 바이트 코드가 생성되는 것으로 보인다.
소스 코드는 변경되지 않았는데, 바이트 코드가 변경되는 특이한 상황이었던 것 같다.