일반 메서드]이번 범위는
객체지향으로 본격적으로 들어가기 전에,
일반 메서드를 직접 만들고 호출하는 기본을 먼저 익히는 단계다.
지금은클래스 메서드,인스턴스 메서드를 정확히 나누는 것이 중심이 아니다.
이번에는 먼저 일반 메서드가 왜 필요한지, 어떻게 만들고 호출하는지, 값을 어떻게 받고 돌려주는지를 이해하는 것이 핵심이다.
즉, 이번 정리는 객체지향으로 들어가기 전에 알아야 하는
메서드의 가장 기본 형태를 정리한 내용이라고 보면 된다.
1. 일반 메서드란 무엇인가
개념
일반 메서드는 이름을 붙여 놓은 코드 블록이다.
자주 쓰는 코드를 한곳에 묶어 두고, 필요할 때마다 이름으로 불러서 다시 사용할 수 있게 만든다.
예를 들어 같은 출력문을 여러 번 써야 한다면, 그 코드를 매번 복사해서 적는 대신 메서드 하나로 묶어 두는 편이 훨씬 깔끔하다.
그래서 메서드는 코드 중복을 줄이고, 프로그램 흐름을 보기 쉽게 만드는 역할을 한다.
함수와 메서드의 차이간단하게 보면
함수는 독립적으로 호출하는 코드 단위이고,
메서드는 객체나 클래스에 속해 있는 코드 단위라고 이해하면 된다.
아주 단순하게 말하면 아래처럼 볼 수 있다.
함수는 그냥 호출 가능메서드는 객체를 통해서 호출다만 지금 배우는 자바 예제는 대부분
static메서드라서 객체 없이도 바로 호출하고 있다.
그래서 이번 단계에서는 자바에서는 이런 코드 묶음을 우선 메서드라고 부른다 정도로 이해하면 충분하다.
왜 필요한가메서드를 배우는 이유는 단순히 문법 하나를 더 외우기 위해서가 아니다.
같은 코드를 여러 번 써야 할 때 메서드로 묶어 두면 다시 쓰기 쉽고,
프로그램을 읽을 때도 “여기서는 이 기능을 호출하는구나” 하고 흐름을 더 빨리 파악할 수 있다.
즉, 메서드는 코드를 줄이는 도구이기도 하지만,
더 중요한 것은 코드를 정리하는 도구라는 점이다.
2. 일반 메서드를 볼 때 먼저 알아야 하는 것
자바에서는 메서드를 클래스 안에 만든다자바에서는 코드를 아무 데나 작성하지 않는다.
메서드는 항상 클래스 안에서 만든다.
즉, 메서드는 혼자 떨어져 있는 것이 아니라
반드시 어떤 클래스 안에 들어 있는 형태로 작성된다.
프로그램은 main 메서드부터 시작한다자바 프로그램을 실행하면 가장 먼저
main메서드가 시작된다.
그래서main은 프로그램의 시작점이라고 보면 된다.
즉, 지금까지 작성한 예제들도 전부
main안에서 다른 메서드를 호출하는 방식으로 실행되고 있다.
메서드는 호출해야 실행된다메서드는 만들어 두기만 한다고 자동으로 실행되지 않는다.
반드시메서드명();처럼 호출문을 써야 안의 코드가 실행된다.
이 점을 먼저 알아야 뒤에서 나오는 예제들이 자연스럽게 이해된다.
제어자란 무엇인가메서드 앞에는 필요에 따라
제어자가 붙을 수 있다.
제어자는 그 메서드를 어디서 사용할 수 있는지, 어떤 방식으로 호출할 수 있는지를 나타내는 말이다.
예를 들어public,static같은 것들이 제어자다.public static void main(String[] args) {위 코드에서
public→ 다른 곳에서도 접근할 수 있게 하는 제어자static→ 객체를 만들지 않고도 사용할 수 있게 하는 제어자라고 보면 된다.
제어자는 붙일 수도 있고 안 붙일 수도 있으며, 여러 개를 함께 붙일 수도 있다.
지금 단계에서는public,static의 깊은 의미를 전부 외우기보다,
메서드 앞에는 이런 제어자가 붙을 수 있다 정도로 먼저 이해하면 충분하다.
메서드의 구성 요소메서드는 보통 아래 요소들로 이루어진다.
제어자 반환형 메서드명(매개변수 선언) { 실행할 코드 return 반환값; }여기서 봐야 할 것은 다음과 같다.
제어자: 메서드를 어떻게 사용할지 정하는 부분반환형: 메서드가 끝난 뒤 어떤 타입의 값을 돌려줄지메서드명: 메서드의 이름매개변수: 호출할 때 값을 받기 위한 변수{ }안쪽 : 실제로 실행할 코드또 메서드 이름 뒤에는 항상
()가 붙는다.
괄호가 없으면 메서드 호출이 아니라 이름 자체만 가리키는 형태가 된다.
즉, 괄호가 있어야 “메서드를 사용한다”는 뜻이 분명해진다.
앞으로 메서드를 볼 때는
제어자 → 반환형 → 이름 → 괄호 → 실행 코드
이 순서로 보면 훨씬 읽기 쉽다.
메서드 사용하는 방법 문법메서드는 호출하는 방식에 따라 여러 형태로 사용할 수 있다.
메서드명(아규먼트); 변수 = 메서드명(아규먼트); 메서드명(메서드명(아규먼트)); 메서드명(아규먼트) + "입니다";하나씩 보면 아래와 같다.
메서드명(아규먼트);
→ 메서드를 그냥 실행만 하는 형태
변수 = 메서드명(아규먼트);
→ 반환값이 있는 메서드의 결과를 변수에 저장하는 형태
메서드명(메서드명(아규먼트));
→ 반환값이 있는 메서드를 다른 메서드의 인자로 넣는 형태
메서드명(아규먼트) + "입니다";
→ 반환값을 문자열과 이어 붙이는 형태즉, 반환값이 있는 메서드는 하나의 값처럼 다양하게 사용할 수 있다.
반대로void메서드는 값을 돌려주지 않기 때문에 이런 식으로 값처럼 사용할 수 없다.
3. 반환값이 없는 가장 기본 메서드
개념메서드를 처음 배울 때는 가장 단순한 형태부터 보는 것이 좋다.
가장 기본적인 메서드는
- 값을 받지 않고
- 값을 돌려주지도 않고
- 호출되면 정해진 일을 수행하는 메서드
이다.
이 형태를 먼저 이해해야 그다음에매개변수,반환값,형변환같은 내용이 자연스럽게 이어진다.
또 여기서void는 값을 돌려주지 않는다는 뜻이다.
필요하면return;을 사용해 실행을 끝낼 수도 있다.
즉,void메서드에서의return;은
값을 보내는 문장이 아니라 메서드 실행을 끝내는 문장으로 이해하면 된다.
예제:
MethodTest1package day4; public class MethodTest1 { public static void main(String[] args) { System.out.println("main() 수행시작"); printMyName(); System.out.println(1); printMyName(); System.out.println(2); printMyName(); System.out.println(3); System.out.println("main() 수행종료"); } static void printMyName() { System.out.println("유니코"); return; } } // 출력결과 // main() 수행시작 // 유니코 // 1 // 유니코 // 2 // 유니코 // 3 // main() 수행종료이 코드는
printMyName()이라는 메서드를 만들어 두고 여러 번 호출하는 예제다.
printMyName()은 괄호 안에 아무것도 없으므로 받는 값이 없다.
또void이므로 돌려주는 값도 없다.
대신 호출되면"유니코"를 출력하는 일을 수행한다.
즉, 이 예제는 메서드는 이렇게 만들고, 이렇게 부르면 실행되는구나를 가장 단순하게 보여준다.
핵심 포인트이 코드에서 핵심은 두 가지다.
- 첫째,
printMyName()은 한 번 만들어 두면 여러 번 다시 쓸 수 있다.- 둘째, 메서드는 호출한 위치로 돌아온 뒤 그다음 문장을 계속 실행한다.
즉, 가장 기본적인 메서드는
값을 받지도 않고, 값을 돌려주지도 않지만, 호출되면 정해진 일을 수행하는 메서드다.
헷갈리기 쉬운 부분메서드는 정의만 했다고 자동 실행되지 않는다.
printMyName();처럼 호출해야 실행된다.
또main은 예외적으로 프로그램 시작 시 자동으로 실행되지만,
그 안에서 만든 다른 메서드들은 직접 호출해야 한다.
4. 반환값이 있는 메서드
개념이번에는 실행만 하는 메서드가 아니라,
작업한 결과를 돌려주는 메서드를 본다.
이런 메서드는void대신int,double,String같은 반환형을 쓴다.
그리고 메서드 끝에서return 값;형태로 결과를 돌려준다.
반환값이 없으면 에러가 난다.static String getMyName() { "유니코"; // 에러!! }즉, 반환값이 있는 메서드는
실행 + 결과 전달까지 함께 하는 메서드다.
예제:
MethodTest1_1package day4; public class MethodTest1_1 { public static void main(String[] args) { System.out.println("[호출 예시1]"); System.out.println(getMyName()); System.out.println("[호출 예시2]"); String name = getMyName(); System.out.println(name); System.out.println(name); } static String getMyName() { return "유니코"; } } // 출력결과 // [호출 예시1] // 유니코 // [호출 예시2] // 유니코 // 유니코이 코드의
getMyName()은"유니코"라는 문자열을 돌려주는 메서드다.
반환형이String이므로, 메서드가 끝날 때 문자열 값을 돌려주고 있다.
이 예제에서는 그 반환값을 두 가지 방식으로 사용한다.
- 첫째,
System.out.println(getMyName());처럼 바로 출력한다.- 둘째,
String name = getMyName();처럼 변수에 저장한 뒤 다시 사용한다.
핵심 포인트반환값이 있는 메서드는 호출만 하고 끝나는 것이 아니라
결과 하나를 호출한 곳으로 넘겨준다는 점이 중요하다.
즉,void메서드와 달리
반환값이 있는 메서드는 실행 결과를 꺼내서 다시 사용할 수 있다.
헷갈리기 쉬운 부분반환값이 있는 메서드는 반드시
return 값;이 필요하다.
그냥 값만 써 놓는다고 반환되는 것이 아니다.
즉, 메서드 선언부에String,int,double같은 반환형을 적었다면
마지막에는 그에 맞는 값을return으로 돌려줘야 한다.
5. 매개변수와 인자
개념이제 메서드가 값을 받아서 동작하는 구조를 본다.
메서드를 선언할 때 괄호 안에 적는 변수는매개변수(parameter)다.
그리고 메서드를 호출할 때 실제로 넘기는 값은인자(argument)다.
즉, 매개변수는 받는 쪽 변수,
인자는 전달하는 쪽 실제 값이라고 이해하면 된다.
예제:
MethodTest2package day4; public class MethodTest2 { public static void main(String[] args) { System.out.println("main() 수행시작"); printMyName(5); System.out.println("main() 수행종료"); } static void printMyName(int num) { if (num <= 0) return; for(int i=1; i <= num; i++) System.out.println("유니코"); } } // 출력결과 // main() 수행시작 // 유니코 // 유니코 // 유니코 // 유니코 // 유니코 // main() 수행종료이 예제는 값을 하나 받아서 동작하는 메서드다.
printMyName(5)라고 호출하면5가num에 들어가고, 그 값만큼 반복해서 출력한다.
즉, 이 예제는
매개변수 하나를 받는 가장 기본적인 형태를 보여준다.
또if (num <= 0) return;이 있기 때문에,
받은 값에 따라 메서드 실행이 중간에 끝날 수도 있다는 점도 함께 볼 수 있다.
예제:
MethodTest3package day4; public class MethodTest3 { public static void main(String[] args) { System.out.println("main() 수행시작"); printMyName(1, '#'); System.out.println("--------------"); printMyName(3, '*'); System.out.println("--------------"); printMyName(2, '@'); System.out.println("--------------"); printMyName((int)3.14, '%'); System.out.println("main() 수행종료"); } static void printMyName(int num, char deco) { for(int i=1; i <= num; i++) System.out.println(deco+"유니코"+deco); } } // 출력결과 // main() 수행시작 // #유니코# // -------------- // *유니코* // *유니코* // *유니코* // -------------- // @유니코@ // @유니코@ // -------------- // %유니코% // %유니코% // %유니코% // main() 수행종료이 메서드는 두 개의 값을 받는다.
int numchar deco그리고 그 값을 이용해 몇 번 출력할지, 어떤 문자로 꾸밀지를 결정한다.
이 예제를 보면 같은 메서드라도
어떤 인자를 넘기느냐에 따라 결과가 달라진다는 점이 바로 보인다.
핵심 특징매개변수와 인자를 사용할 때는 세 가지를 꼭 맞춰야 한다.
- 개수
- 순서
- 타입
예를 들어(int, char)형태로 받는 메서드라면
호출할 때도 그 순서대로 맞춰서 넘겨야 한다.
형변환이 필요한 경우이 예제의 마지막 줄은 아래와 같다.
printMyName((int)3.14, '%');여기서 첫 번째 매개변수는
int이므로,3.14를 그대로 넣을 수 없다.
그래서(int)3.14처럼 형변환해서 넣고 있다.
즉,
printMyName(3, '%')→ 가능printMyName(3.14, '%')→ 불가능printMyName((int)3.14, '%')→ 가능이 흐름으로 이해하면 된다.
헷갈리기 쉬운 부분매개변수와 인자는 이름이 비슷해서 자주 헷갈린다.
- 매개변수 → 메서드가 받는 변수
- 인자 → 호출할 때 넘기는 실제 값
이 둘을 구분해서 이해해야 뒤에서 나오는 예제들이 잘 보인다.
6. 매개변수와 반환값이 함께 있는 메서드
개념앞에서는
- 반환값 없는 메서드
- 반환값 있는 메서드
- 매개변수를 받는 메서드
를 따로 봤다.
이제는 이 둘이 합쳐진 형태를 본다.
즉, 값을 받아서 작업하고, 그 결과를 다시 돌려주는 메서드다.
이 형태가 실전에서 가장 자주 쓰이는 기본 구조다.
예제:
MethodTest1_2package day4; public class MethodTest1_2 { public static void main(String[] args) { System.out.println(getSum(100, 200)); int r1 = getSum(10, 20); System.out.println("결과값 : " + r1); System.out.println(getAvg(r1, 30)); double r2 = getAvg(15, 20); System.out.println(r2); System.out.println((int)r2); } static int getSum(int num1, int num2) { return num1+num2; } static double getAvg(double num1, double num2) { return (num1+num2)/2; } } // 출력결과 // 300 // 결과값 : 30 // 30.0 // 17.5 // 17
getSum은int두 개를 받아서 더한 결과를int로 돌려준다.
getAvg는double두 개를 받아서 평균을double로 돌려준다.
즉, 이 예제는
입력값을 받아 계산하고, 결과값을 반환하는 메서드를 가장 기본적으로 보여준다.
예제:
MethodTest5package day4; public class MethodTest5 { public static void main(String[] args) { System.out.println("main() 수행시작"); int result = operate(10,20); System.out.println("호출 결과1 : "+result); System.out.println("호출 결과2 : "+operate(100,200)); int result2 = operate(11,22) % 2; if(result2 == 0) System.out.println("호출 결과3 짝수"); else System.out.println("호출 결과3 홀수"); System.out.println("호출 결과4 : "+operate(100,200,300)); System.out.println(getName()); System.out.println("*" + getName() + "*"); System.out.println("main() 수행종료"); } static int operate(int num1, int num2) { return num1+num2; } static int operate(int num1, int num2, int num3) { return num1+num2+num3; } static String getName() { return "김정현"; } } // 출력결과 // main() 수행시작 // 호출 결과1 : 30 // 호출 결과2 : 300 // 호출 결과3 홀수 // 호출 결과4 : 600 // 김정현 // *김정현* // main() 수행종료이 예제는 매개변수와 반환값이 함께 있는 메서드를
실제로 어떻게 활용하는지 보여준다.
int result = operate(10,20);→ 변수에 저장System.out.println("호출 결과2 : "+operate(100,200));→ 바로 출력operate(11,22) % 2→ 연산식에 사용"*" + getName() + "*"→ 문자열과 결합즉, 값을 받아 계산한 뒤 돌려준 결과는
다시 여러 형태로 활용할 수 있다.
핵심 포인트이 파트에서 중요한 것은 아래 흐름이다.
1. 값을 받는다.
2. 메서드 안에서 계산한다.
3.return으로 결과를 돌려준다.
4. 호출한 쪽에서 그 결과를 사용한다.이 흐름이 이해되면 메서드의 기본 골격은 거의 잡힌 것이다.
메서드 안에서의 형변환
getAvg는 매개변수가double이다.
그런데 호출할 때int값을 넣은 부분이 있다.System.out.println(getAvg(r1, 30)); double r2 = getAvg(15, 20);여기서는
int값이double로 바뀌어서 들어간다.
즉, 호출할 때 타입이 완전히 같지 않아도 자동 형변환이 가능한 경우에는 호출할 수 있다.
헷갈리기 쉬운 부분반환형이
int면int결과를 돌려줘야 하고,
반환형이double이면double결과를 돌려줘야 한다.
즉,return뒤에 오는 값은
메서드 선언부의 반환형과 맞아야 한다는 점을 꼭 기억해야 한다.
7. 일반 메서드 활용
7-1. 같은 이름의 메서드 만들기 - 오버로딩
개념
오버로딩은 같은 이름의 메서드를 여러 개 만드는 것이다.
단, 아무렇게나 만들 수 있는 것은 아니고
매개변수의 개수나 타입이 달라야 한다.
즉, 자바는 메서드를 구분할 때
이름만 보는 것이 아니라 괄호 안의 매개변수 모양까지 함께 본다.
보기 1 그림은 매개변수의 타입이 같기 때문에 오버로딩 성립 ❌
보기 2 그림은 리턴타입이 달라서 어떤 메서드가 호출된 것인지 알 수가 없기 때문에 오버로딩 성립 ❌
두 메서드 모두 각각 다른 타입의 매개변수를 가지고 있기 때문에 오버로딩 성립 🅾️
예제:
MethodTest4_1package day4; public class MethodTest4_1 { public static void main(String[] args) { System.out.println("main() 수행시작"); printMyName(3, '*'); printMyName("듀크", '$'); printMyName("듀크", '$'); printMyName("듀크", '$'); printMyName("턱시", '!'); System.out.println("main() 수행종료"); } static void printMyName(int num, char deco) { for(int i=1; i <= num; i++) System.out.println(deco+"유니코"+deco); } static void printMyName(String name, char deco) { System.out.println(deco+name+deco); } } // 출력결과 // main() 수행시작 // *유니코* // *유니코* // *유니코* // $듀크$ // $듀크$ // $듀크$ // !턱시! // main() 수행종료이 예제에는
printMyName이라는 메서드가 두 개 있다.
이름은 같지만 매개변수 모양이 다르다.
그래서 자바는 호출할 때 넘긴 인자를 보고
어떤 메서드를 실행할지 구분할 수 있다.
헷갈리기 쉬운 부분반환형만 다르고 매개변수가 같으면
오버로딩이 아니다.
오버로딩은 어디까지나 매개변수로 구분한다.
7-2. 배열을 매개변수로 전달하기
개념메서드는 숫자 하나, 문자 하나만 받는 것이 아니다.
배열도 매개변수로 받을 수 있다.
배열을 넘기면 여러 값을 한꺼번에 처리하는 메서드를 만들 수 있어서
메서드 활용 범위가 훨씬 넓어진다.
예제:
MethodTest6package day5; public class MethodTest6 { public static void main(String[] args) { System.out.println("main() 수행시작"); System.out.println(add(10, 100)); System.out.println(add(10, 20, 30)); int nums[] = {10, 20, 30, 40}; System.out.println("nums의 값 : "+nums); System.out.println(add(nums)); System.out.println(add(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); System.out.println(add(new int[5])); System.out.println("main() 수행종료"); } static int add(int p1, int p2) { return p1+p2; } static int add(int p1, int p2, int p3) { return p1+p2+p3; } static int add(int[] p) { System.out.println("p의 값 : "+p); int sum = 0; for(int i=0; i < p.length; i++) sum += p[i]; return sum; } } // 출력결과 // main() 수행시작 // 110 // 60 // nums의 값 : [I@2b2fa4f7 // p의 값 : [I@2b2fa4f7 // 100 // p의 값 : [I@7ad041f3 // 55 // p의 값 : [I@251a69d7 // 0 // main() 수행종료이 예제는
add를 여러 형태로 만든다.
- 값 2개를 더하는 메서드
- 값 3개를 더하는 메서드
- 배열 전체를 더하는 메서드
즉, 같은 “더하기” 기능이더라도
받는 데이터 모양에 따라 메서드를 다르게 만들 수 있다.
헷갈리기 쉬운 부분
add(10, 20, 30, 40)처럼 4개를 바로 넘길 수는 없다.
그 형태로 받는 메서드가 없기 때문이다.
그래서 4개 이상을 넘기고 싶다면
지금처럼 배열에 담아서 보내는 방식을 사용할 수 있다.
배열을 매개변수로 넘기는 방식은 가장 기본적인 형태다.
가변 인자(...)는 이 방식을 더 편하게 사용할 수 있게 만든 문법이라고 보면 된다.
7-3. 가변 인자(...) 사용하기
개념배열을 매개변수로 전달하면 여러 값을 한꺼번에 처리할 수 있다.
그런데 자바에서는 배열을 직접 만들어 넘기는 방식 외에도,
가변 인자(...)를 사용해서 값의 개수를 유동적으로 받을 수 있다.
가변 인자는 메서드 선언에서 아래처럼 쓴다.int... p이렇게 선언하면 호출할 때 값을 몇 개 넘길지 미리 정해 두지 않아도 된다.
즉,2개,3개,5개,0개처럼 개수가 달라도 한 메서드가 받을 수 있다.
결국 가변 인자는 여러 개의 값을 편하게 받기 위한 문법이고,
메서드 안에서는 배열처럼 사용할 수 있다.
핵심 특징
...는 매개변수 선언에서만 사용할 수 있다.- 가변 인자는 항상 마지막 매개변수여야 한다.
- 메서드 안에서는 배열처럼
length와 인덱스를 사용할 수 있다.- 자바
5부터 추가된 문법이다.
예제:
MethodTest6_1package day5; public class MethodTest6_1 { public static void main(String[] args) { System.out.println("main() 수행시작"); System.out.println(add(10, 100)); System.out.println(add(10, 20, 30)); System.out.println(add(new int[]{10, 20, 30, 40})); System.out.println(add(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})); System.out.println(add(new int[0])); System.out.println(add()); System.out.println(add(10, 20, 30, 40, 50)); System.out.println(add(11, 22, 33, 44, 55, 66, 77, 88, 99)); System.out.println("main() 수행종료"); } static int add(int p1, int p2) { return p1 + p2; } static int add(int p1, int p2, int p3) { return p1 + p2 + p3; } static int add(int... p) { int sum = 0; for(int i = 0; i < p.length; i++) sum += p[i]; return sum; } }이렇게 가변 인자를 사용하면 호출할 때 배열을 직접 만들지 않고도 아래처럼 쓸 수 있다.
add(); add(10, 20, 30, 40, 50); add(11, 22, 33, 44, 55, 66, 77, 88, 99);즉, 배열을 직접 만들어 넘기지 않아도 여러 값을 바로 나열해서 전달할 수 있다는 점이 가변 인자의 가장 큰 장점이다.
MethodTest6은 배열로 여러 값을 받는 방식,
MethodTest6_1은 가변 인자로 더 편하게 받을 수 있다는 확장 설명으로 보면 된다.
헷갈리기 쉬운 부분가변 인자는 리턴값을 배열로 받는 문법이 아니다.
어디까지나 매개변수를 가변적으로 받는 문법이다.
즉,
int... p→ 여러 값을 매개변수로 받는 것char[] getName(...)→ 배열을 결과로 반환하는 것이 둘은 서로 다른 개념이다.
7-4. 배열을 반환하기
개념메서드는 배열을 받을 수도 있고,
반대로 배열 자체를 결과로 돌려줄 수도 있다.
즉, 결과값 하나만 반환하는 것이 아니라
여러 값을 담은 배열 전체를 반환할 수 있다는 뜻이다.
예제:
MethodTest8package day5; public class MethodTest8 { public static void main(String[] args) { System.out.println("main() 수행시작"); char[] returnValue = getName(true); System.out.println(returnValue); System.out.println(getName(!true)); System.out.println("main() 수행종료"); } static char[] getName(boolean type) { char ary[]; if(type) ary = new char[] {'J', 'A', 'V', 'A'}; else ary = new char[] {'P', 'Y', 'T', 'H', 'O', 'N'}; return ary; } } // 출력결과 // main() 수행시작 // JAVA // PYTHON // main() 수행종료이 메서드는
char[]배열을 반환한다.
조건에 따라JAVA또는PYTHON글자를 담은 배열을 만들어 돌려준다.
여기서 중요한 점은 반환형이char[]라는 것이다.
즉, 문자 하나가 아니라 문자 배열 전체를 결과로 넘기고 있다.
헷갈리기 쉬운 부분
char[]는println()에서 문자처럼 보이지만,
모든 배열이 이런 식으로 출력되는 것은 아니다.
예를 들어int[]같은 배열은 보통
값 대신 배열의 참조 정보처럼 보인다.
7-5. 원본 배열을 바꾸는 경우와 새 배열을 만드는 경우
개념배열을 다루는 메서드는 비슷해 보여도
동작 방식이 다를 수 있다.
- 새 배열을 만들어서 반환하는 방식
- 원본 배열 자체를 직접 바꾸는 방식
이 둘은 결과가 다르므로 구분해서 이해해야 한다.
예제:
MethodTest9package day5; public class MethodTest9 { public static void main(String[] args) { int p1[] = { 20, 10, 14, 30}; printArray(p1); int[] result = updateArray1(p1); printArray(result); printArray(p1); System.out.println("-------------------"); updateArray2(p1); printArray(p1); } public static void printArray(int[] p2) { for(int d : p2) System.out.printf("%d ", d); System.out.printf("\n"); } static int[] updateArray1(int[] p2) { int[] result = new int[p2.length]; for(int i=0; i < result.length;i++) result[i] = p2[i] * 2; return result; } static void updateArray2(int[] p3) { for(int i=0; i < p3.length;i++) p3[i] = p3[i] * 2; } }
updateArray1은 새 배열을 만들어서 반환한다.
그래서 원래 배열p1은 그대로 남는다.
반면updateArray2는 전달받은 배열 자체를 직접 수정한다.
그래서 메서드가 끝난 뒤 원본p1의 값이 바뀐다.
핵심 포인트둘 다 “배열 값을 2배로 만든다”는 점은 같지만
결과는 다르다.
updateArray1→ 원본 유지updateArray2→ 원본 변경문제에 따라 원본을 남겨야 할 수도 있고,
원본을 바로 바꿔도 될 수도 있기 때문에 이 차이를 알아야 한다.
7-6. main(String[] args)
개념
main메서드의String[] args는 그냥 외우는 문법이 아니다.
프로그램 실행 시 전달되는 문자열들을 받는 문자열 배열 매개변수다.
즉, 프로그램을 실행할 때 넘긴 값들이
args배열에 들어온다고 이해하면 된다.
예제:
MethodTest7package day5; public class MethodTest7 { public static void main(String[] args) { System.out.println("main() 수행시작"); System.out.println(args.length); System.out.println("main() 수행종료"); } } // 출력결과 // 실행 시 넘긴 문자열 개수만큼 숫자가 출력됨이 예제는 전달받은 문자열 개수가 몇 개인지 보여준다.
즉,args가 실제로 배열처럼 들어온다는 점을 가장 단순하게 확인하는 예제다.
예제:
MethodTest7_1package day5; public class MethodTest7_1 { public static void main(String[] args) { String result=""; for(int i=0; i <args.length; i++) result = result + args[i]; System.out.println(result); } } // 출력결과 예시 // 실행 시 Java Is Fun 을 넘기면 // JavaIsFun이 코드는 실행할 때 받은 문자열들을 이어 붙여서 출력한다.
예제:
MethodTest7_2package day5; public class MethodTest7_2 { public static void main(String[] args) { int result=0; for(int i=0; i <args.length; i++) result = result + Integer.parseInt(args[i]); System.out.println(result); } } // 출력결과 예시 // 실행 시 10 20 30 을 넘기면 // 60이 코드는 전달받은 문자열을 숫자로 바꾼 뒤 더한다.
헷갈리기 쉬운 부분
args는 숫자 배열이 아니라 문자열 배열이다.
그래서"10","20"을 바로 더하는 것이 아니라
먼저Integer.parseInt()로 숫자로 바꿔야 한다.
[응용 예제 / 실습]
응용 예제 - 2차원 배열 출력 코드를 메서드로 분리하기
문제에서 무엇을 하려는지이 예제는
2차원 배열을 출력하는 코드를 따로 메서드로 빼서,
같은 기능을 여러 번 반복해서 사용할 수 있게 만드는 연습이다.
즉, 중복되는 출력 코드를 정리하고,
필요할 때마다 다시 호출하는 흐름을 익히는 것이 핵심이다.
이 예제에서 사용된 개념
메서드 선언메서드 호출2차원 배열배열 매개변수- 이중
for문- 향상된
for문
코드 흐름먼저
5행 3열짜리2차원 배열을 만든다.
처음에는 배열 안에 값이 들어 있지 않으므로0으로 채워진 상태다.
이 상태를printTwoArray(nums)메서드로 한 번 출력한다.
그다음 중첩 반복문을 사용해서 배열 안에 값을 채운다.
이후 다시printTwoArray(nums)를 호출해서 바뀐 배열 상태를 출력한다.
즉, 이 예제는
배열을 채우는 코드와 배열을 출력하는 코드를 나눠서,
출력 기능만 따로 메서드로 분리한 구조를 보여준다.
같은2차원 배열을 출력하더라도,
출력 로직을 메서드로 빼 두면 필요할 때마다 다시 사용할 수 있다는 점이 중요하다.
코드 예제예제:
MethodTest10_1package day5; public class MethodTest10_1 { public static void main(String[] args) { int[][] nums = new int[5][3]; int num = 1; printTwoArray(nums); System.out.println(); for (int j = 0; j < nums[0].length; j++) { for (int i = j; i < nums.length - j; i++) nums[i][j] = num++; } printTwoArray(nums); } static void printTwoArray(int[][] nums) { for (int[] rowData : nums) { for (int elem : rowData) System.out.print(elem + "\t"); System.out.println(); } } } // 출력결과 // 0 0 0 // 0 0 0 // 0 0 0 // 0 0 0 // 0 0 0 // // 1 0 0 // 2 6 0 // 3 7 9 // 4 8 0 // 5 0 0
헷갈리기 쉬운 부분이 예제에서 중요한 것은 숫자를 어떻게 채우는지보다,
출력 기능을 왜 따로 메서드로 뺐는지를 보는 것이다.
printTwoArray(nums)가 없다면 같은 출력문을 두 번 직접 써야 한다.
하지만 메서드로 분리해 두면 한 줄로 다시 호출할 수 있다.
또printTwoArray(int[][] nums)처럼2차원 배열도 매개변수로 받을 수 있다는 점도 함께 확인해야 한다.
즉, 메서드는 단순한 값 하나만 받는 것이 아니라 배열 전체도 받을 수 있다.
참고이번 예제들은 대부분
static메서드로 작성되어 있다.
왜 이렇게 호출할 수 있는지는객체지향에서 다시 정리하면 된다.
이 정도면일반 메서드는
왜 필요한지 → 어떻게 읽는지 → 가장 쉬운 형태 → 반환값 → 매개변수 → 활용
순서로 자연스럽게 복습할 수 있다.