본문 바로가기
멀티캠퍼스 풀스택 과정/Java의 정석

자바의 정석2-3 메서드의 개념(return문, 호출스택)

by 이쟝 2021. 12. 31.

메서드

작업 단위로 문장들을 묶어서 이름 붙인 것

메서드 호출(사용)

(입력)을 받아서 처리하고, 결과를 반환(출력)

-> 같은 작업을 하는 코드를 메서드로 묶고 그 메서드를 호출하면 코드가 훨씬 간결해짐!

 

메서드의 기본 구조

-> 메서드는 반드시 클래스 안에 있어야 하고 함수는 상관 xx(클래스 독립적)

 

메서드의 장점

1) 코드의 중복 코드 제거

2) 코드의 관리용이

3) 코드를 재사용 가능

4) 코드가 간결해서 이해하기 쉬워짐

 

메서드의 작성

- 반복적으로 수행되는 여러 문장을 메서드로 작성(반복적이지 않더라도 긴 코드면)

- 하나의 메서드는 한 가지 기능만 수행하도록 작성


메서드의 구조 

 

메서드 = 선언부 + 구현부

메서드의 선언부 

1) 반환 타입 (int + int --> int)

2) 메서드 이름 (add)

3) 매개변수(입력), 작업에 필요한 값들 0~n개 가능 (2개의 매개변수 int a, int b)

 

-> 반환값(출력값)은 1개만!! 반환 값이 여러 개이면 배열로! 반환 값이 없으면 void

 

메서드의 구현부

지역변수(lv): 메서드영역 내에 선언된 변수

 

핑크색으로 표시된 부분은 지역 변수

- (int x, int y) -> 입력값을 받는 매개변수, int x, int y, result 지역변수

- 메소드 두 영역이 겹치지 않기 때문에 변수 이름이 같아도 상관 xx


메서드의 호출

메서드 이름(값 1, 값 2, …);  // 메서드를 호출하는 방법 -> 괄호안에는 작업에 필요한 값을 입력

print99danAll( );      // void print99danAll( )을 호출 (void -> 출력할 값이 없다)

int result = add(3,5);  // 메서드 add(int x, int y)를 호출하고, 결과를 result에 저장

-> 작업결과를 저장할 변수(result) 필요!

 

 

- 메서드를 호출한 쪽에서 준 값을 add 메서드한테 전달하는 중간 매개체 역할을 한다고 해서 매개변수이다!(parameter)


예제) 더하기 빼기 곱하기 나누기 최댓값 메서드 있는 클래스 만들어서 활용해보기

 

출력 값

add(5L, 3L) = 8

subtract(5L, 3L) = 2

multiply(5L, 3L) = 15

divide(5L, 3L) = 1.0

Max(5,3) = 5  

 

public class Method1 {

	public static void main(String[] args) {
		MyMath mm = new MyMath();
		long result = mm.add(5L, 3L);  // add메서드 호출
		long result2 = mm.subtract(5L, 3L);  // subtract메서드 호출
		long result3 = mm.multiply(5L, 3L);  // multiply메서드 호출
		double result4 = mm.divide(5, 3);    // divide메서드 호출
		long resultMax = mm.max(5,3);        // max메서드 호출
		
		System.out.println("add(5L, 3L) = " + result);
		System.out.println("subtract(5L, 3L) = " + result2);
		System.out.println("multiply(5L, 3L) = " + result3);
		System.out.printf("divide(5L, 3L) = %.1f%n", result4);
		System.out.println("Max(5,3) = " + resultMax);
	}
}
class MyMath {
	long add(long a, long b) {
		long result = a + b;
		return result;
		//return a + b; // 위의 두 줄을 이와 같이 한 줄로 간단히 할 수 있음
		                //작업을 마치면 호출한 곳으로 돌아음
	}
	long subtract(long a, long b) { return a - b; }
	long multiply(long a, long b) { return a * b; }
	double divide(long a, long b) { return a / b; }
	
	//두 값을 받아서 둘중에 큰 값을 반환하는 메서드 작성
	long max(long i, long j) {
		long result = 0;
		result = i > j ? i : j; //i가 j보다 크면 result에 i값을 넣어라! 아니면 j값을 넣어라!
		return result;
	}
}

메서드의 실행 흐름

 


return문, 반환 값

실행 중인 메서드를 종료하고 호출한 곳으로 되돌아간다. 

-> 항상 메서드가 끝나면 return을 반환해줘야 하는데 위 예제는 void가 있어서 return 생략 가능!(컴파일러가 메서드의 마지막에 return;을 자동적으로 추가해줌)

 

반환타입이 void가 아닌 경우, 반드시 return문 필요!

 

두 번째 조건식이 거짓일 때의 (b가 a보다 크다면) return이 없기 때문에 에러가 남!

그래서 에러를 해결하기 위해

 

int max(int a, int b) {
    if(a > b) 
        return a; // 조건식이 참일 때 실행된다.
    else 
        return b; // 조건식이 거짓일 때 실행된다.

 

-> 이렇게 변경해줘야 함

 

메서드 타입 == 반환타입 == 결과를 담을 변수의 타입

int result = mm. add(3, 5);                           

    int add(int x, int y) {

          return x + y;

    }

 

예제 printGugudan 메서드 입력받은 수가 2~9사이의 구구단을 출력

 

void printGugudan(int dan) {
		if(!(2 <= dan && dan <= 9))
			return; // 입력받은 단(dan)이 2~9가 아니면, 메서드 종료하고 돌아가기
		
		for(int i=1; i<=9; i++) { 
			System.out.printf("%d x %d = %d%n", dan, i, dan*i);
		}
		return; //생략가능
	}

 

더보기

dan에 int3이 들어오게 되면 if문에는 거짓이 되어서 for문으로 넘어가게 됨

for문이 실행되면서 2 x 1 = 2 하고 리턴, 2 x 2 = 4 하고 리턴 , 2 x 3 = 6 하고 리턴 ...

 


 

호출 스택(call stack)

메서드 수행에 필요한 메모리가 제공되는 공간으로

메서드가 호출되면 호출스택에 메모리 할당, 종료되면 해제

 

스택(stack): 밑이 막힌 상자. 위에 차곡차곡 쌓인다.

 

집어넣은 순서대로 차곡차곡 쌓인다.
집어넣은 순서대로 차곡차곡 쌓인다.
위에서부터 차례대로 꺼낸다.
위에서부터 차례대로 꺼낸다.

 

->1번과 2번 사이에 무언가를 집어넣거나 1번을 뺄 수는 없다.

 

1) main 메서드실행상태

2) main 메서드가 println 메서드를 호출하면

3) main 메서드대기상태가 되고, println은 실행상태가 된다.

1) println 메서드 종료

2) 스택에서 사라지게 되고 main 메서드로 돌아와서 실행상태로 바뀜

 

-> 호출 스택에선 아래 있는 메서드가 위의 메서드를 호출한 것

-> 하나의 스택에서는 하나의 메서드(맨 위)만 실행되고 나머지는 대기 중

 

 

호출스택 생성

② main 메서드 실행

③ main 메서드에서 println 메서드 호출하고 main 메서드 대기, println이 화면에 Hello를 출력하고 사용했던 메모리를 반환하면서 스택에서 사라지게 됨

④main 메서드로 돌아가서 main 메서드 실행

더 이상 실행할 문장이 없어서 프로그램 종료