본문 바로가기

Backend/Java

[JAVA] 메소드 (Method)

 

 

 


 

메소드(Method) 알아보기

국비지원수업 11일차

 


 

 

 

1. 메소드(Method)란?


메소드(Method)

- 클래스 내의 함수

- 데이터를 입력 받아 어떠한 기능을 수행한 후 결과값을 내놓는 단위 실행 코드

 

메소드의 특징

- 명령들을 모아서 단위(그룹)으로 정의

- 메소드마다 고유한 이름이 존재

- 메소드의 이름을 불러 실행(명령, 호출(call))하면 그룹안의 코드들이 실행되는 형식

- 자바의 메소드는 이름 옆에 항상 (괄호)가 달려있음

ex) System.out.print(); / Math.random() / 문자데이터.equals() / 문자데이터.compareTo() - import하지 않아도 됨

 

메소드의 목적

- 그룹안의 코드들을 재활용

- 명령들의 단순 실행이 아닌, 메소드 내 코드들에게 연산 또는 일정 기능을 부여하기 위해 사용

- 메소드 호출 후 메소드에서 계산된 결과를 호출한 지점에서 리턴받아서 사용

 

메소드 사용 방법

1. 간헐적으로 반복되는 코드들을 별도로 정의(작성)

2. 정해놓은 이름으로 코드들을 불러서 실행

 

 

 

2. 메소드 생성과 호출


개발자가 임의로 만든 메소드 생성 가능 위치

- class 내부

- main 외부

 


2-1. 메소드 생성

public static void (메소드이름)() {   }

* public / static / void 의 의미는 이후 설명, 우선 기본 문법으로 생각

- 메소드를 만든다고 해서 무조건 실행되는 것이 아닌, main에서 '생성한 메소드의 이름'을 불러 호출해야 실행됨

- main 메소드는 JDK가 프로그램을 처음 시작할 때 호출

- 메소드의 이름을 만드는 규칙 == 변수 이름을 만드는 규칙

- 메소드를 작성할 때, 메소드를 생성하고 main에서 호출하는 것을 권장

* main에서 호출을 먼저할 경우 전달인수, 매개변수 수정 시 코드가 꼬일 수 있음 (에러방지)

 

public static void abc() {
    System.out.println("첫번째 Print 메서드가 실행되고 있어요~!!");
    System.out.println("두번째 Print 메서드가 실행되고 있어요~!!");
    System.out.println("세번째 Print 메서드가 실행되고 있어요~!!");
    System.out.println("네번째 Print 메서드가 실행되고 있어요~!!");
}

 

 

 


2-2. 메소드 호출

위에서 생성한 메소드 코드를 main에서 호출하는 예제

// 자바가 호출하는, 프로그램의 실행을 돕는 메소드
public static void main(String[] args) {

    System.out.println("프로그램이 시작되었습니다 -------------");
    System.out.println("main 메서드가 실행되고 있습니다 -------------\n");

    System.out.println("main 메서드가 호출됩니다 -------------");
    abc(); // 메소드를 호출해야 실행, 실행의 제어권이 넘어감
    System.out.println("@ abc 메서드를 실행하고 돌아왔습니다 -------------\n");
    System.out.println("아직 main 메서드가 실행되고 있습니다 -------------\n");

    System.out.println("main 메서드가 호출됩니다 -------------");
    abc();
    System.out.println("@ abc 메서드를 실행하고 돌아왔습니다 -------------\n");
    System.out.println("프로그램을 종료합니다 -------------");

}

 

 

 

3. 전달인수가 존재하는 메소드의 형식


int n = 100;

myPrint1();
// 전달인수는 직접 리터럴(500)을 넣을수도 있고 변수(n)를 이용해서 값을 넣을수도 있음
myPrint2(200); // 괄호 안에 메서드의 입력값 넣어줌 (전달인수)
myPrint2(n);
myPrint3(100, 200.0, "Korea");
myPrint4(100, 200, 300);

 

1. 전달인수 X

ex) myPrint();

2. 숫자, 문자 등을 직접 대입

ex) myPrint(100);

3. 변수를 이용한 대입

ex) myPrint(num);

4. 같은 자료형을 여러개 대입

ex) myPrint(num1, num2, num3);

5. 자료형을 혼합한 대입

ex) myPrint(num1, num2, String1, String2);

 

 


3-1. 지역변수와 매개변수

public static void main(String[] args) {
    int n = 100;

    myPrint1();
    myPrint2(200);
}
    
public static void myPrint1() {
    int n = 200; // 지역변수
    System.out.println("myPrint1 메서드의 지역변수 n값 : " + n);
}

// i : 매개변수 - 주로 호출할 때 보내주는 전달인수가 저장
public static void myPrint2(int i) {
    System.out.println("myPrint2 메서드의 매개변수 i값 : " + i);
}

 

매개변수는 메소드안에서 생성된 걸로 인식되는 ' 지역변수 '

 

- main에 있는 변수 n과 myPrint1 메소드의 n 변수는 서로 독립적

- main 안의 변수값을 다른 메소드에서 출력하고 싶다면 별도의 조치로 호출과 함께 전달

ex) myPrint2와 같이 메소드에 매개변수 설정

 

 

예시

public static void main(String[] args) {

    // 정수 하나를 입력 받아서 그 정수에 해당하는 구구단 출력
    // 구구단 출력은 메서드를 이용해서 출력, 메서드 이름 googoodan

    Scanner sc = new Scanner(System.in);

    System.out.print("정수를 입력하세요 : ");
    int dan = sc.nextInt();
    googoodan(dan);
    
}

public static void googoodan(int dan) {
    for(int i = 1; i <= 9; i++)
        System.out.printf("%d x %d = %d\n", dan, i, dan*i);
}

 

호출되는 메소드의 매개변수와 호출하는 지역에서 보내주는 전달인수(변수)는 이름이 같아도, 달라도 무방

* 어차피 각 메소드의 지역변수로, 서로 다른 변수 취급

 

값에 의한 호출 (Call By Value)

- 전달인수로 변수를 지정했다면, 변수가 전달되는 것이 아닌 변수에 저장된 값의 복사본이 전달

* 호출된 메소드의 연산으로부터 원본은 아무런 영향을 받지 않음

 

 


 

3-2. 여러개의 매개변수

public static void main(String[] args) {
    myPrint3(100, 200.0, "Korea");
}
private static void myPrint3(int n, double d, String s) {
    System.out.println("전달받은 정수 : " + n);
    System.out.println("전달받은 실수 : " + d);
    System.out.println("전달받은 문자 : " + s);
}

 

매개변수는 필요에 따라 여러개 생성하여 사용가능

- 매개변수가 여러개라면 호출할 때 그 순서와 자료형에 맞게 전달인수를 넣어야함

 

 

매개변수는 각각 생성

// 매개변수는 같은 자료형이 여러개라도 동시에 생성하지 않고 각각 생성
// private static void myPrint4(int i, j, k){	} // 에러
private static void myPrint4(int i, int j, int k) {
    ...
}

 

같은 자료형이 여러개라도 변수처럼 동시에 생성하지 못함

 

 


3-3. 매개변수 배열

전달인수가 배열일 경우, 배열의 참조값(주소값)을 전달

 

Call By Reference

- 전달인수로 참조값을 전달, 하나의 배열을 두개의 메소드가 공유해서 사용

- 배열의 주소만 전달하기 때문에 배열의 요소 갯수 상관없이 전달 가능

 

public static void main(String[] args) {

    int[] arr = { 50, 60, 80, 70, 20, 10, 60, 120, 64, 150 };
    // int[] arr = new int[10];

    // prnMax2(arr[0], arr[1], arr[2]); // 비효율, 전달인수 제한 등의 단점
    prnMax(arr); // 배열의 참조값을 전달

    System.out.println("prnMax에서 변경한 a[0]의 값 : " + arr[0]); // a[0] == 9999
}

private static void prnMax(int[] a) {
    // int[] a = main에서 생성된 new int[10];의 주소를 저장한 셈

    int max = a[0];
    for(int i=0; i<a.length; i++)
        if(max < a[i]) max = a[i];

    System.out.println("전달된 배열의 값 중 가장 큰 값 : " + max);

    a[0] = 9999; // 참조값 증명
}

 

 

 


3-4. 같은 자료형인 다수의 매개 변수가 필요한 메소드

public static void main(String[] args) {
    int sumValue = sum(5, 8, 7, 4, 5, 54, 1, 58, 54);
    System.out.println("입력값들의 합은 " + sumValue + "입니다");
}

// 비효율
private static int sum(int i, int j, int k, int l, int m, int n, int o, int p, int q) {
    return i+j+k+l+m+n+o+p+q;
}

 

(자료형)... (변수) 형태로 데이터 전달

- 같은 자료형의 전달인수 양이 너무 많을 경우 전달인수를 int...a 와 같은 형태의 매개변수로 받을 수 있음

- 이러한 형태의 매개변수는 배열처럼 사용

 

 

자료형이 혼합되어 있는 경우 (아래 예시처럼 String 데이터와 ... 데이터가 전달)

- 추가로 전달할 전달인수 & 매개변수가 있다면 반드시 int... a가 마지막에 위치

* 그렇지 않으면, 배열에 전달되는 int 값들이 몇개인지 구분이 되지 않아 에러 발생

if) ..., order 의 형태라면, 정수데이터가 이어지는 건지, 정수데이터가 끝나고 order이 들어가는 건지 경계가 모호

 

 

예시

public static void main(String[] args) {
    sort("asc", 78, 25, 56, 32, 45, 78, 98);
    sort("desc", 87, 75, 23, 65, 45, 8, 56, 98, 78, 12);
}

public static void sort(String order, int... a) {
    if(order.equals("asc")) { // 오름차순
        for (int i = 0; i < a.length; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[i] > a[j]) {
                    int temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
        
        System.out.print("오름차순 정렬 : ");
        
    }else { // 내림차순	order.equals("desc")
        for (int i = 0; i < a.length; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[i] < a[j]) {
                    int temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
        
        System.out.print("내림차순 정렬 : ");     
    }

    for(int k:a)
        System.out.printf("%d ", k);
    System.out.println();
}

 

 

 

4. 메소드의 리턴값


public static void ....

- 메소드 생성 시 void 자리는 리턴형의 유형을 지정

- void : 리턴할 값이 없음

- 이 자리에 다른 자료형의 키워드를 쓰면, 그 유형의 자료가 리턴되어야 한다는 뜻

 

 

리턴값이 있는 메소드 즉시 활용

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    System.out.print("정수를 입력하세요 : ");
    int num = sc.nextInt();

    System.out.println("입력한 정수의 제곱 : " + square(num));
}

private static int square(int num) {
    int result = num * num;
    System.out.println("입력한 정수의 제곱 : " + result);

    return result;
}

 

 

 

리턴값 변수 저장

메소드가 호출되고 계산해서 리턴해준 값 result를 변수에 저장할 수도 있음

- 연산식의 결과를 왼쪽 변수에 대입하듯 저장

ex) (변수) = (메소드);

- 아래와 같이 num 변수에 담긴 값을 main 메소드에서 활용가능

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    System.out.print("정수를 입력하세요 : ");
    num = sc.nextInt();

    int result = square(num);
    System.out.println("입력한 정수의 제곱 : " + result);
}

 

 

 

리턴이 있는 메소드를 호출했으나 리턴값을 받아줄 변수를 사용하지 않았을 때

// 리턴이 있는 메서드를 호출하고 그 리턴값을 받아줄 수 없는 변수를 쓰지 않았을 때, 문법적 오류는 없지만 열심히 계산한 결과를 버리는 셈
max(25, 48, 36);

 

max 메소드를 리턴값이 있는 메소드라 가정

- 문법적 오류는 없으나 계산한 결과를 버리는 셈

 

 

 

5. 메소드 오버로딩 (Overloading)


메소드 오버로딩 (Overloading)

메소드의 이름은 같으나 매개변수의 타입, 개수, 순서가 다르면 서로 다른 메소드로 인지하는 문법

- 일관된 메소드 이름을 사용하여 사용자가 직관적으로 파악할 수 있게 함

 

- 메소드 사용 시 '전달인수의 개수, 자료형, 순서'는 '매개변수의 전달인수의 개수, 자료형, 순서'와 반드시 동일해야 함

( == 메소드 호출이 되려면 전달인수와 동일한 형태의 매개변수를 갖는 메소드가 필요 )

* (착각금지!) 오버로딩이 많이 되었다고 해서 정의되지 않은 형태의 전달인수의 개수, 자료형, 순서를 임의로 사용하여 호출할 수 없음

 

 

예시

public static void main(String[] args) {
    int maxValue = max(56, 32);
    System.out.println("56, 32 중 가장 큰 값은 " + maxValue + "입니다");

    double maxValueD = max(123.12, 456.56);
    System.out.println("123.12, 456.56 중 가장 큰 값은 " + maxValueD + "입니다");
}

public static int max(int i, int j) {
    if(i > j) return i;
    else return j;
}

public static double max(double d, double e) {
    if(d > e) return d;
    else return e;
}

 

 

 

 

 

 

'Backend > Java' 카테고리의 다른 글

[JAVA] 클래스 생성자(Constructor)  (0) 2024.10.14
[JAVA] 클래스(Class) 생성과 사용  (0) 2024.10.07
[JAVA] 배열 (Array), 2차원 배열  (0) 2024.09.27
[JAVA] 연산자 (Operator)  (0) 2024.09.24
[JAVA] System.out.printf()  (0) 2024.09.24