메서드가 존재하는 이유
메서드는 이름을 호출할 때마다 실행할 수 있는, 이름이 붙은 코드 블록입니다. 같은 줄을 몇 번이고 다시 쓰는 대신, 그것을 메서드 안에 한 번만 작성하고 필요한 만큼 여러 번 호출합니다. 그러면 프로그램이 더 짧아지고, 읽기 쉬워지며, 고치기도 훨씬 쉬워집니다. 한곳에서 로직을 바꾸면 호출하는 모든 곳이 그 변경을 받게 되니까요.
여러분은 이미 메서드를 호출해 왔습니다. System.out.println(...)도 메서드 호출이고, list.size()도 그렇습니다. 이제 여러분만의 메서드를 작성하게 됩니다.
메서드 선언하고 호출하기
메서드 선언은 네 부분으로 이루어집니다. 반환 타입, 이름, (매개변수를 위한) 괄호 한 쌍, 그리고 중괄호로 감싼 본문입니다. 다음은 가장 작으면서도 쓸모 있는 예제로, 어떤 작업을 수행하고 아무것도 반환하지 않는 메서드입니다.
static void printGreeting()의 각 부분을 읽어 봅시다.
static: 객체를 만들지 않고도main이 직접 호출할 수 있게 해 줍니다(아래에서 더 다룹니다).void: 이 메서드는 아무 값도 반환하지 않습니다.printGreeting: 호출할 때 사용하는 이름입니다.(): 빈 괄호는 입력을 받지 않는다는 뜻입니다.
메서드는 이름 뒤에 괄호를 써서 호출합니다. main 안의 두 호출이 본문을 두 번 실행하므로, 인사말이 두 번 출력됩니다.
값 반환하기
대부분의 메서드는 무언가를 계산해 return으로 돌려줍니다. 이름 앞의 반환 타입은 어떤 종류의 값이 나오는지를 말해 줍니다. 여기서는 int입니다.
square(5)는 25로 평가되며, 이를 변수에 저장하거나 출력하거나 더 큰 식 안에서 사용할 수 있습니다. 메서드 호출은 그것이 반환하는 값을 대신합니다. return이 실행되는 순간 메서드는 끝나고 제어는 호출한 쪽으로 되돌아갑니다. 같은 경로에서 return 뒤에 오는 코드는 절대 실행되지 않습니다.
반환 타입과 반환되는 값은 일치해야 합니다. int로 선언해 놓고 return "text";를 시도하는 것은 컴파일 오류입니다. 컴파일러가 이 약속을 강제합니다.
void와 반환 타입의 비교
구분은 간단합니다. 호출한 쪽이 값을 돌려받아야 할 때는 실제 반환 타입을 쓰고, 메서드가 그저 무언가를 하기만 할 때(출력, 저장, 상태 갱신)는 void를 씁니다.
void logMessage(String msg) // 작업을 하지만 아무것도 반환하지 않는다
int add(int a, int b) // 호출한 쪽이 사용하는 값을 계산한다
초보자가 흔히 하는 실수는 void 메서드의 "결과"를 사용하려는 것입니다.
int x = printGreeting(); // 컴파일 오류: printGreeting()은 void를 반환한다
대입할 값이 없으므로 이것은 컴파일되지 않습니다. void 메서드의 결과를 원하게 된다면, 그것은 그 메서드가 무언가를 반환해야 한다는 신호입니다.
분기하며 일찍 반환하는 메서드
return은 여러 곳에서 할 수 있습니다. 답을 알게 되는 즉시 일찍 반환하는 편이, 모든 것을 else 안에 중첩하는 것보다 더 명확하게 읽히는 경우가 많습니다.
각 return은 즉시 빠져나가므로, 처음으로 일치하는 조건이 이깁니다. 다만 값을 반환하는 메서드를 지나는 모든 경로가 return으로 끝나는지 꼭 확인하세요. 어떤 분기가 아무것도 반환하지 않고 통과할 수 있다면 컴파일러는 "missing return statement"라고 항의합니다. 여기서 마지막 return "F";가 어느 조건에도 걸리지 않은 경우를 처리합니다.
여기서 static의 의미
위의 모든 메서드가 static이라는 것을 눈치챘을 수도 있습니다. static 메서드는 어떤 객체가 아니라 클래스 자체에 속하므로, (마찬가지로 static인) main이 이름으로 직접 호출할 수 있습니다. static이 없으면 메서드는 인스턴스에 속하고, 그것을 호출하려면 객체가 필요합니다.
지금은 로직이 main 곁에 있는 작은 프로그램을 작성하는 동안, 보조 메서드를 static으로 표시해 같은 방식으로 호출할 수 있게 하세요. 자신만의 클래스와 객체를 만들기 시작하면 비정적(인스턴스) 메서드도 작성하게 됩니다. 그것은 클래스 장에서 다룹니다.
지역 변수는 메서드 안에 머문다
메서드 안에서 선언된 변수는 그 안에서만 존재합니다. 메서드가 실행될 때 만들어지고, 반환될 때 사라집니다. 호출한 쪽은 그것들을 결코 보지 못합니다.
total과 i는 전적으로 sumTo 안에서만 삽니다. 메서드 밖으로 빠져나가는 유일한 것은 여러분이 return하는 값입니다. 이 격리는 장점입니다. 각 메서드는 자기 완결적인 단위라서, 그 임시 변수가 밖으로 새어 나가거나 다른 곳의 이름과 충돌할 걱정 없이 추론할 수 있습니다.
다음: 메서드 매개변수
여기서 다룬 메서드는 모두 입력을 받지 않거나 값 하나를 받았습니다. 진짜 힘은 데이터를 안으로 전달하는 데서 나옵니다. 그리고 자바에는 인자가 어떻게 전달되는지, 객체와 기본형에서 무엇이 다른지, 매개변수에 기본값과 비슷한 대체값을 어떻게 줄지에 대한 구체적인 규칙이 있습니다. 그것이 다음 페이지의 내용입니다.
자주 묻는 질문
자바에서 메서드란 무엇인가요?
메서드는 이름을 호출해 필요할 때 실행할 수 있는, 이름이 붙은 코드 블록입니다. 하나의 작업을 한곳에 모아 두어, 같은 줄을 반복하는 대신 재사용할 수 있게 해 줍니다. 메서드는 입력(매개변수)을 받아 결과(반환값)를 돌려줄 수도 있고, 작업만 하고 아무것도 반환하지 않을 수도 있습니다(void).
자바에서 메서드를 만들고 호출하려면 어떻게 하나요?
반환 타입, 이름, 괄호를 붙여 선언합니다: static int square(int n) { return n * n; }. 그런 다음 괄호 안에 인자를 넣어 이름으로 호출합니다: int result = square(5);. 아무것도 반환하지 않는 메서드는 void를 사용하며, printGreeting();처럼 단독 문장으로 호출합니다.
자바 메서드에서 void는 무슨 뜻인가요?
void는 메서드가 아무 값도 반환하지 않는다는 뜻입니다. 작업(예를 들어 출력)은 수행하지만 호출한 쪽에 아무것도 돌려주지 않습니다. void 메서드의 결과는 변수에 대입할 수 없습니다. 메서드가 호출한 쪽이 사용할 값을 만들어 내야 한다면, int나 String 같은 실제 반환 타입을 지정하고 대신 return을 사용하세요.