메서드

정순동·2023년 12월 3일
0

자바기초

목록 보기
24/89

메서드

메서드란? 메서드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은것이다. 수학의 함수라고
생각하면 편하다.
수학과 다른점은 결과값이 없을수도 있고 심지어는 입력과 출력 둘 다 없을수도 있다.

메서드는 원하는 값을 넣어 원하는 결과만 얻어내면 될 뿐 해당 메서드가 어떻게 구성돼있는지 알 필요는 없다. 지금까지 사용한 Math클래스의 메서드들이나 print()메서드 등도 어떻게 구성돼있는지 모르지만 잘 사용하지 않았는가?

메서드는 선언부와 구현부로 나누어져 있다.

	public static int getId (String fileName)  - 선언부 (header)
    {
    	someService......();
        ...
        ...									   - 구현부 (body)
        ...
    	return id;
    }

메서드의 선언부

메서드의 선언부는 이름, 매개변수, 반환타입으로 구성되어 있다.
이 이름의(보통 기능으로 이름을 짓는다.)메서드를 활용하기 위해 어떤 매개변수가 필요하고 어떤 타입의 결과가 반환되는지 간략하게 확인할 수 있다.
아래 코드는 대충 봐도 x 와 y를 더하는 메서드임을 알 수 있다.

	public static int add(int x, int y) {  //여기서 add가 이름 add앞의 int가 반환타입 ()안의 변수들은 매개변수다
    	return x + y; // 반환 타입을 int로 했으니 int가 return으로 주어져야 한다.
    }

매개변수 선언(parameter declaration)

매개변수는 메서드가 작업을 수행하는데 필요한 값들(입력)을 제공받기 위한 것이며, 필요한 값의 개수만큼 변수를 선언하며 각 변수 간의 구분은 수미표','를 사용한다. 한 가지 주의할 점은 일반적인 변수선언과 달리 두 변수의 타입이 같아도 변수의 타입을 생략할 수 없다는 것이다.

	int add(int x, int y) { ... } // OK.
    int add(int x, y) 	  { ... } // 에러. 매개변수 y의 타입이 없다.

반환타입(return type)

메서드의 작업수행 결과인 반환값의 타입을 적는다. 굳이 반환값이 필요 없는 경우에는 void를 적어주면 된다.

	public static void sayHi() {
    	System.out.println("Hi!");
    }

위 메서드는 그저 "Hi!"를 출력해주는 메서드이다. 따라서 매개변수도 필요없고 리턴할 데이터도 없으니 void로 처리했다.

메서드의 구현부

메서드 선언부 다음에 오는 괄호{}를 구현부(body)라고 한다.

return문

메서드의 반환타입이 void가 아니라면 무언가를 반환해 주어야 할 것이다. 이 때 return 바로옆에 반환값을 적어주면 된다. 만약 메서드의 선언문에서 반환타입을 int로 해 주었다면 아래와 같은 코드가 좋은 예시가 될 것이다.

	public static int add(int x, int y) {
    	return x + y; // 반환 타입이 int이니 int로 return해 주는 모습.
    }

지역변수(local variable)

메서드 내에 선언된 변수들은 그 메서드 내에서만 사용할 수 있으므로 서로 다른 메서드라면 같은 이름의 변수를 선언해도 된다.

	public static int add(int x, int y) {
    	int result = x + y;
        return result;
    }
    
    public static int sub(int x, int y) {
    	int result = x - y;
        return result;
    }

둘 다 똑같은 매개변수 이름, 리턴시 똑같은 result라는 변수이름으로 겹치는 것이 상당히 많지만 각각 add와 sub의 지역변수로써 선언됐기 때문에 문제가 없다.

메서드의 호출

메서드를 정의했다면 이제 호출할 수 있다. 위에 작성했던 add()와 sub()함수를 사용한다면 아래와 같이 사용할 수 있을것이다.

	int result = add(5, 3);	// add함수 내에서 5와 3을 더해 8을 반환하고 그 값이 result에 저장된다.
    System.out.println(result); // 8
    혹은
    System.out.println(add(5,3)); // 따로 result라는 변수에 저장하지 않고 한번 출력 용도로만 사용하는것이다.

인수(argument)와 매개변수(parameter)

메서드를 호출할 때 괄호() 안에 지정해준 값들을 '인수(argument)'또는 '인자'라고 한다.
메서드를 선언할 때 괄호() 안에 지정해준 값들은 '매개변수(parameter)'라고 한다.

선언한 메서드를 호출할때는 매개변수의 개수와 인수의 개수를 같게 해 주어야 한다.

	public static int add(int x, int y) {
    	int result = x + y;
        return result;
    }
    
    add(5, 3); // OK. 인수와 매개변수 둘 다 타입과 개수가 맞음
    add(5, 3, 5, 6); // 에러. 인수와 매개변수의 개수가 맞지 않음
    add(5, "안녕하세요"); // 에러. 인수와 매개변수의 타입이 맞지 않음

호출스택(call stack)

호출스택이란? 메서드의 작업에 필요한 메모리 공간을 제공한다. 메서드가 호출되면, 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간 결과 등을 저장하는데 사용된다. 그리고 메서드가 작업을 마치면 할당됐던 메모리 공간은 반환되어 비워진다.

호출스택을 조사해 보면 메서드 간의 호출 관계와 현재 수행중인 메서드가 어느 것인지 알 수 있다.

호출스택의 특징
1. 메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당받는다.
2. 메서드가 수행을 마치고 나면 사용했던 메모리를 반환하고 스택에서 제거된다.
3. 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.
4. 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드이다.

매개변수의 기본형과 참조형

자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다.
이 때 매개변수가 기본형이라면 데이터가 그대로 복사돼 넘어간다. 하지만 참조형이라면 주소가 넘어가기 때문에 넘어간 참조형의 주소로 지정된 곳의 데이터를 바꿀 수 있다.

기본형 매개변수
변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수
변수의 값을 읽고 변경할 수 있다.(read & write)

static 메서드와 인스턴스 메서드

변수에서 그랬던 것과 같이, 메서드 앞에 static이 붙어 있으면 클래스메서드이고 붙어 있지 않으면 인스턴스 메서드이다.

static을 언제 붙여야 할까?

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
  • 생성된 각 인스턴스는 서로 독립적이기 때문에 각 인스턴스의 변수(iv)는 서로 다른 값을 유지한다. 그러나 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 static을 붙여서 클래스 변수로 정의해야 한다.
  1. 클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
  • static이 붙은 변수(클래스변수)는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문이다.
  1. 클래스 메서드(static메서드)는 인스턴스 변수를 사용할 수 없다.
  • 인스턴스변수는 인스턴스가 반드시 존재해야만 사용할 수 있는데, 클래스메서드(static이 붙은 메서드)는 인스턴스 생성 없이 호출 가능하므로 클래스 메서드가 호출됐을 때 인스턴스가 존재하지 않을 수도 있다. 그래서 클래스 메서드에서 인스턴스변수의 사용을 금지한다.
    반면에 인스턴스 변수나 인스턴스 메서드에서는 static이 붙은 멤버들을 사용하는 것이 언제나 가능하다. 인스턴스 변수가 존재한다는 것은 static변수가 이미 메뢰에 존재한다는 것을 의미하기 때문이다.
  1. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
  • 메서드의 작업내용 중에서 인스턴스변수를 필요로 한다면, static을 붙일 수 없다. 반대로 인스턴스변수를 필요로 하지 않는다면 static을 붙이자. 메서드 호출 시간이 짧아지므로 성능이 향상된다. static을 안 붙인 메서드(인스턴스메서드)는 실행 시 호출되어야 할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다
  • 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살피고 있으면, static을 붙여준다.
  • 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.

메서드의 오버로딩(overloading)

메서드도 변수와 마찬가지로 같은 클래스 내에서 서로 구별될 수 있어야 하기 때문에 각기 다른 이름을 사용해야 하지만, 만약 같은 이름의 메서드에 매개변수의 개수 혹은 타입이 다르다면 이는 같은이름으로 사용할 수 있다.

오버로딩의 조건
1. 메서드 이름이 같아야한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
3. 반환 타입은 관계없다.

아래와 같이 2개이상, 다른타입의 매개변수의 위치를 바꿔서 오버로딩도 가능하다

	long add(int a, long b) { return a + b; }
    long add(long a, int b) { return a + b; }

사실 위의 예는 살짝 위험할 수 있다. 저렇게 간단한 코드인 경우 상관없지만 구현부의 코드가 서로 다르다면 매개변수의 위치로만 메서드를 판별하기란 쉽지 않을것이기 때문이다.

0개의 댓글