코드 한 줄의 기록

Java 메서드 완전 정복: 정의부터 오버로딩, 가변인자까지 한 번에 마스터하기 본문

JAVA

Java 메서드 완전 정복: 정의부터 오버로딩, 가변인자까지 한 번에 마스터하기

CodeByJin 2025. 9. 30. 07:51
반응형

프로그래밍을 공부하다 보면 메서드라는 개념을 꼭 만나게 되는데요. 처음에는 이게 왜 필요한지, 어떻게 사용하는지 막막하게 느껴질 수 있어요. 저도 처음 자바를 배울 때 메서드 개념이 어려웠는데, 이제는 메서드 없이는 프로그래밍이 불가능하다고 생각할 정도로 중요한 개념이라는 걸 깨달았습니다.

오늘은 제가 자바 메서드를 공부하면서 정리한 내용을 여러분과 공유해보려고 해요. 메서드의 기본 정의부터 시작해서 호출 방법, 오버로딩, 가변인자까지 차근차근 알아보겠습니다.

메서드가 뭔가요?

메서드는 쉽게 말해서 특정한 기능을 수행하는 코드 블록이에요. 마치 수학에서 함수와 비슷한 개념이죠. 어떤 입력값을 받아서 처리한 후 결과를 반환하거나, 단순히 어떤 작업을 수행하는 역할을 합니다.

실생활로 예를 들어보면, "계산기"를 생각해볼 수 있어요. 계산기에서 더하기 버튼을 누르면 두 숫자를 더해주잖아요? 메서드도 마찬가지로 "더하기"라는 기능을 담당하는 코드 덩어리라고 생각하면 이해하기 쉬워요.

메서드를 사용하는 이유

메서드를 사용하는 가장 큰 이유는 코드의 재사용성가독성 때문이에요. 같은 기능을 여러 번 사용해야 할 때, 그때마다 똑같은 코드를 반복해서 작성할 필요 없이 메서드 하나만 만들어두고 필요할 때마다 호출하면 되거든요.

또한 복잡한 프로그램을 작은 단위로 나누어 관리할 수 있어서 코드를 이해하고 수정하기도 훨씬 쉬워집니다.

메서드 정의하는 방법

자바에서 메서드를 정의하는 기본 구조는 다음과 같아요.

[접근제어자] [반환타입] 메서드이름(매개변수목록) {
    // 실행할 코드
    return 결과값; // 반환타입이 void가 아닌 경우
}

 

각 부분을 하나씩 살펴볼게요.

1. 접근제어자

  • public: 어디서든 접근 가능
  • private: 같은 클래스 내에서만 접근 가능
  • protected: 같은 패키지나 상속받은 클래스에서 접근 가능
  • default: 같은 패키지 내에서만 접근 가능

2. 반환타입

메서드가 작업을 완료한 후 돌려줄 값의 타입을 지정해요. 돌려줄 값이 없으면 void를 사용합니다.

 

3. 메서드 이름

메서드의 기능을 잘 나타내는 이름을 지어주는 게 좋아요. 자바에서는 메서드 이름을 camelCase로 작성하는 것이 관례입니다.

4. 매개변수 목록

메서드가 작업을 수행하는 데 필요한 입력값들을 정의해요[21]. 없어도 괜찮습니다.

 

실제 예제를 살펴보기

// 두 숫자를 더하는 메서드
public int add(int a, int b) {
    int result = a + b;
    return result;
}

// 인사말을 출력하는 메서드
public void sayHello(String name) {
    System.out.println("안녕하세요, " + name + "님!");
}

// 매개변수와 반환값이 모두 없는 메서드
public void printCurrentTime() {
    System.out.println("현재 시간: " + System.currentTimeMillis());
}

 

메서드 호출하는 방법

메서드를 정의했으면 이제 호출해서 사용해야겠죠? 메서드 호출은 다음과 같은 형태로 합니다.

[객체명.]메서드이름(인자값들);

 

호출 예제

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public void printResult(int result) {
        System.out.println("결과: " + result);
    }
    
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        
        // 메서드 호출
        int sum = calc.add(10, 20);
        calc.printResult(sum);
        
        // 메서드 호출 결과를 바로 다른 메서드의 인자로 사용
        calc.printResult(calc.add(5, 15));
    }
}

 

return문과 void 타입

메서드에서 return문은 두 가지 역할을 해요.

  1. 값을 반환: 메서드의 실행 결과를 호출한 곳으로 돌려줍니다.
  2. 메서드 종료: return문을 만나면 메서드 실행이 즉시 종료됩니다.

void 메서드의 return

반환값이 없는 void 메서드에서도 return을 사용할 수 있어요.  이때는 단순히 메서드를 종료하는 용도로 사용됩니다.

public void checkNumber(int number) {
    if (number < 0) {
        System.out.println("음수는 처리할 수 없습니다.");
        return; // 여기서 메서드 종료
    }
    
    System.out.println("입력된 숫자: " + number);
    // 음수가 아닌 경우에만 이 부분이 실행됨
}

메서드 오버로딩 (Method Overloading)

오버로딩은 같은 이름의 메서드를 여러 개 만드는 기능이에요. 단, 매개변수의 개수나 타입이 달라야 합니다.

 

오버로딩이 가능한 경우

public class MathUtils {
    // 두 정수를 더하는 메서드
    public int add(int a, int b) {
        return a + b;
    }
    
    // 세 정수를 더하는 메서드 (매개변수 개수가 다름)
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 두 실수를 더하는 메서드 (매개변수 타입이 다름)
    public double add(double a, double b) {
        return a + b;
    }
    
    // 문자열을 연결하는 메서드 (매개변수 타입이 다름)
    public String add(String a, String b) {
        return a + b;
    }
}

 

오버로딩이 불가능한 경우

메서드의 리턴타입은 오버로딩에 영향을 주지 않습니다.

// 이런 경우는 오버로딩이 안 됩니다!
public int calculate(int a, int b) {
    return a + b;
}

// 반환타입만 다르고 매개변수가 같으면 오버로딩 불가
public double calculate(int a, int b) {  // 컴파일 에러!
    return a + b;
}

 

오버로딩을 사용하는 이유

오버로딩을 사용하면 비슷한 기능을 하는 메서드들을 같은 이름으로 묶어서 관리할 수 있어요.

예를 들어, System.out.println() 메서드도 오버로딩된 메서드예요. int, String, boolean 등 다양한 타입의 값을 출력할 수 있죠.

public static void main(String[] args) {
    MathUtils math = new MathUtils();
    
    System.out.println(math.add(1, 2));           // int + int
    System.out.println(math.add(1, 2, 3));       // int + int + int
    System.out.println(math.add(1.5, 2.5));      // double + double
    System.out.println(math.add("Hello", "World")); // String + String
}

가변인자 (Varargs)

가변인자는 메서드에 몇 개의 인자가 들어올지 모를 때 사용하는 기능이에요.

Java 5부터 도입되었고, ... 기호를 사용해서 표현합니다.

 

가변인자 사용법

public int sum(int... numbers) {
    int total = 0;
    for (int number : numbers) {
        total += number;
    }
    return total;
}

 

이렇게 정의한 메서드는 다음과 같이 호출할 수 있어요.

public static void main(String[] args) {
    Calculator calc = new Calculator();
    
    System.out.println(calc.sum(1));           // 1개 인자
    System.out.println(calc.sum(1, 2));        // 2개 인자
    System.out.println(calc.sum(1, 2, 3));     // 3개 인자
    System.out.println(calc.sum(1, 2, 3, 4, 5)); // 5개 인자
    System.out.println(calc.sum());            // 인자 없음도 가능
}

 

가변인자의 내부 동작

가변인자는 내부적으로 배열로 처리됩니다.

위의 sum 메서드에서 numbers는 실제로는 int[] 배열이에요.

public void printNumbers(int... numbers) {
    System.out.println("전달받은 숫자 개수: " + numbers.length);
    for (int i = 0; i < numbers.length; i++) {
        System.out.println("numbers[" + i + "] = " + numbers[i]);
    }
}

 

가변인자 사용 시 주의사항

  1. 한 메서드에 가변인자는 하나만 사용할 수 있어요.
  2. 가변인자는 매개변수 목록의 마지막에 와야 해요.
// 올바른 사용법
public void method1(String name, int... scores) { }

// 잘못된 사용법
public void method2(int... scores, String name) { } // 컴파일 에러!
public void method3(int... scores1, int... scores2) { } // 컴파일 에러!

 

  3. 성능 고려사항: 가변인자는 호출할 때마다 새로운 배열을 생성하므로, 성능이 중요한 상황에서는 주의해야 해요.

 

가변인자의 실용적인 예제

public class Logger {
    public void log(String level, String... messages) {
        System.out.print("[" + level + "] ");
        for (String message : messages) {
            System.out.print(message + " ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        Logger logger = new Logger();
        
        logger.log("INFO", "애플리케이션이 시작되었습니다.");
        logger.log("ERROR", "데이터베이스", "연결", "실패");
        logger.log("DEBUG", "사용자", "로그인", "시도:", "admin");
    }
}

main 메서드 특별히 알아보기

main 메서드는 자바 프로그램의 진입점(Entry Point)이에요. JVM이 프로그램을 실행할 때 가장 먼저 찾아서 실행하는 메서드죠.

public static void main(String[] args) {
    // 프로그램 시작점
}

 

main 메서드의 각 키워드 의미

  • public: JVM이 어디서든 접근할 수 있어야 하므로
  • static: 객체 생성 없이 호출할 수 있어야 하므로
  • void: 프로그램이 끝나면 반환할 곳이 없으므로
  • String[] args: 명령행에서 전달받는 인자들

args 매개변수 활용하기

public static void main(String[] args) {
    if (args.length > 0) {
        System.out.println("전달받은 첫 번째 인자: " + args[0]);
        
        for (int i = 0; i < args.length; i++) {
            System.out.println("args[" + i + "] = " + args[i]);
        }
    } else {
        System.out.println("전달받은 인자가 없습니다.");
    }
}

 

매개변수와 인자의 차이점

이 부분은 많은 사람들이 헷갈려하는 부분인데요.

  • 매개변수(Parameter): 메서드를 정의할 때 사용하는 변수
  • 인자(Argument): 메서드를 호출할 때 실제로 전달하는 값
public int multiply(int x, int y) {  // x, y는 매개변수
    return x * y;
}

public static void main(String[] args) {
    Calculator calc = new Calculator();
    int result = calc.multiply(3, 4);  // 3, 4는 인자
}

메서드와 메모리

자바에서 메서드 호출 시 매개변수는 값에 의한 전달(Pass by Value) 방식으로 동작해요.

 

기본형 매개변수

public void changeValue(int num) {
    num = 100;  // 매개변수 값만 변경됨
}

public static void main(String[] args) {
    int number = 10;
    changeValue(number);
    System.out.println(number);  // 여전히 10 출력
}

 

참조형 매개변수

public void changeArray(int[] arr) {
    arr[0] = 100;  // 배열 내용 변경됨
}

public static void main(String[] args) {
    int[] numbers = {1, 2, 3};
    changeArray(numbers);
    System.out.println(numbers[0]);  // 100 출력
}

 

참조형의 경우 객체의 주소값이 복사되어 전달되므로, 객체 내부의 값은 변경될 수 있어요.

실무에서 메서드 활용하기

메서드 체이닝

public class Calculator {
    private int value = 0;
    
    public Calculator add(int num) {
        this.value += num;
        return this;  // 자기 자신을 반환
    }
    
    public Calculator multiply(int num) {
        this.value *= num;
        return this;
    }
    
    public int getValue() {
        return this.value;
    }
    
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        int result = calc.add(10).multiply(2).add(5).getValue();
        System.out.println(result);  // 25 출력
    }
}

 

헬퍼 메서드 만들기

public class StringUtils {
    public static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }
    
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
    }
    
    public static void main(String[] args) {
        System.out.println(capitalize("hello world"));  // Hello world
        System.out.println(isEmpty(""));                // true
        System.out.println(isEmpty("  "));              // true
        System.out.println(isEmpty("hello"));           // false
    }
}

 

메서드는 자바 프로그래밍의 핵심 개념 중 하나예요. 처음에는 복잡해 보일 수 있지만, 한번 익숙해지면 정말 강력한 도구가 됩니다.
오늘 배운 내용을 정리해보면

  1. 메서드 정의: 접근제어자, 반환타입, 메서드명, 매개변수를 올바르게 지정
  2. 메서드 호출: 객체를 통해 메서드를 호출하고 반환값 활용
  3. 오버로딩: 같은 이름으로 다양한 매개변수를 받는 메서드 작성
  4. 가변인자: 유연한 개수의 인자를 받는 메서드 작성
  5. 실무 활용: 메서드 체이닝, 헬퍼 메서드 등 실용적인 패턴

앞으로 코딩할 때 이런 개념들을 활용해보세요. 처음에는 어색할 수 있지만, 연습하다 보면 자연스럽게 좋은 메서드를 작성할 수 있게 될 거예요!

 

Java 배열(1차원/다차원)과 Arrays 유틸리티 완벽 정리: 초보자부터 실무까지 한 번에!

배열은 자바 프로그래밍의 기초 중의 기초라고 할 수 있습니다. 처음 배울 때는 단순해 보이지만, 실제로 활용하다 보면 정말 많은 기능과 메서드들이 있다는 걸 깨닫게 되죠. 이번 글에서는 Java

byteandbit.tistory.com

반응형