메소드 : 어떤 특정 작업을 수행하기 위한 명령문의 집합
{접근제어자} {반환타입} 메소드이름 (매개변수 목록) {
// 실행할 코드
// 반환타입에 맞게 return
// 반환타입이 void 면 return 생략
}
접근제어자 : 메소드에 접근할 수 있는 범위
A. public : 어디서나 접근 가능
B. protected : 상속관계이거나 같은 패키지에서 접근 가능
C. default(생략가능) : 같은 패키지에서 접근 가능
D. private : 같은 클래스 내부에서만 접근 가능
반환타입 : 메소드가 모든 작업을 마치고 반환하는 데이터의 타입
A. void : 리턴값 없음
B. 기본 변수 자료형 : int, float, 등등
C. 오브젝트형 : String, 이외 사용자 정의타입
메소드 이름 : 메소드를 호출하기 위한 이름
매개변수 목록(parameters) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들
실행할 코드 : 메소드의 기능을 수행하는 코드
public class Application1 {
public static void main(String[] args) {
/* 수업목표. 메소드의 호출 흐름에 대해 이해할 수 있다. */
System.out.println("main() 시작함..");
methodA();
System.out.println("main() 종료됨..");
}
public static void methodA() {
System.out.println("methodA() 호출됨..");
methodB();
System.out.println("methodA() 종료됨..");
}
public static void methodB() {
System.out.println("methodB() 호출됨..");
methodC();
System.out.println("methodB() 종료됨..");
}
public static void methodC() {
System.out.println("methodC() 호출됨..");
System.out.println("methodC() 종료됨..");
}
}
main() 시작함..
methodA() 호출됨..
methodB() 호출됨..
methodC() 호출됨..
methodC() 종료됨..
methodB() 종료됨..
methodA() 종료됨..
main() 종료됨..

위의 경우는 메소드 안에서 다른 메소드를 호출한다.
A가 B호출, B가 C호출 -> C 종료된 후 다시 B로 돌아오고 B 종료 -> A 종료 -> main() 종료
다른 경우도 살펴보자.
public class Application2 {
public static void main(String[] args) {
System.out.println("main() 시작함...");
Application2 app = new Application2();
app.methodA();
app.methodB();
app.methodC();
System.out.println("main() 종료됨...");
}
public void methodA() {
System.out.println("methodA() 호출됨...");
System.out.println("methodA() 종료됨...");
}
public void methodB() {
System.out.println("methodB() 호출됨...");
System.out.println("methodB() 종료됨...");
}
public void methodC() {
System.out.println("methodC() 호출됨...");
System.out.println("methodC() 종료됨...");
}
}
이전 예제와는 출력 결과가 다를 것이다. 이전 예제는 메소드가 다른 메소드를 출력하지만 이번 예제는 main이 하나씩 호출하는 것이다.
main이 A호출 -> A종료 후 다시 main이 B호출 -> ... C까지 종료 후 main 종료

왜
Application2 app = new Application2();부분이 필요할까? 이전까지는 없었는데
Application2와 main을 보면 앞에static의 유무에 차이가 있다.
static이 없는 메소드 (non-static method)는 해당 클래스를 인지시킨 후 접근해 호출한다.
static에 관한건 추후에 더 자세하게 정리하겠다.
변수는 main() 안에서만 써왔는데 그런 것들을 지역 변수 라고 한다.
지역변수 : 메소드 안에 적은 변수
전달인자 (argument) : 전달하는 값
매개변수 (parameter) : 괄호 안에 전달인자를 받기 위해 선언하는 변수

전역변수 : 메소드가 아닌 클래스에 적은 변수
클래스(static)변수 : 실행하면 컴퓨터가 이미 알고 있는 변수
public class Application3 {
// 3. 클래스에 쓴 전역변수, 클래스 변수
static int global = 10;
public static void main(String[] args) {
// 메소드 안에 써둔 것 1. 지역변수
int local = 20;
System.out.println("global = " + global);
System.out.println("local 출력 : " + local);
/* 설명. testMethod에 나이를 주고 출력하기 */
Application3 app3 = new Application3();
app3.testMethod(13);
app3.testMethod(19);
app3.testMethod(15);
app3.testMethod('a'); // a는 아스키코드고 97번
app3.testMethod((int)12.34); // int형으로 바꾸면 12
app3.testMethod(3 * 6);
}
/* 설명. 정수형 나이를 주면 문자열을 출력해주는 기능이 있는 메소드 */
public void testMethod(int age) {
System.out.println("당신의 나이는 " + age + "세 입니다.");
}
}
global = 10
local 출력 : 20
당신의 나이는 13세 입니다.
당신의 나이는 19세 입니다.
당신의 나이는 15세 입니다.
당신의 나이는 97세 입니다.
당신의 나이는 12세 입니다.
당신의 나이는 18세 입니다.
/* 목차 1. 여러 개의 전달인자를 이용한 메소드 호출 */
Application4 app4 = new Application4();
app4.testMethod("홍길동", 20, '남');
/* 목차 2. 변수에 저장된 값을 전달하며 호출할 수 있다. */
String name = "유관순";
int age = 20;
char gender = '여';
app4.testMethod(name, age, gender);
}
public void testMethod(String name, int age, final char gender) {
System.out.println("당신의 이름은 " + name + "이고, 나이는 " + age + "세 이며, 성별은 " + gender + "입니다.");
}
당신의 이름은 홍길동이고, 나이는 20세 이며, 성별은 남입니다.
당신의 이름은 유관순이고, 나이는 20세 이며, 성별은 여입니다.
반환 유형이 void를 제외하고는 전부 return이 필요하다.
1. void 형
return: 현재 메소드를 강제 종료하고 호출한 구문으로 다시 돌아가는 명령어
public class Application5 {
public static void main(String[] args) {
/* 수업목표. 메소트 리턴에 대해 이해할 수 있다. */
Application5 app5 = new Application5();
app5.testMethod();
}
public void testMethod() {
System.out.println("testMethod() 동작 확인...");
}
}
testMethod() 동작 확인...
2. return 활용
위에는 void 형이기 때문에 return이 없었지만, 한 번 return이 되게끔 해보자.
public class Application6 {
public static void main(String[] args) {
/* 수업목표. 반환값이 있는 메소드를 작성할 수 있다. */
System.out.println(testMethod());
// 위처럼 해도 되고
// String result = testMethod();
// System.out.println(result); 해도 된다.
}
public static String testMethod() {
System.out.println("test() 메소드 실행함");
return "test";
}
}
test() 메소드 실행함
test
3. 다른 클래스에서 메소드 호출
main()과 함께 있는 클래스에 메소드를 적는 것이 아닌 다른 클래스에 적어보자.
Calculator 클래스
public class Calculator {
public int plusTwoNumbers(int first, int second) {
return first + second;
}
public int minusTwoNumbers(int first, int second) {
return first - second;
}
public int multiplyTwoNumbers(int first, int second) {
return first * second;
}
public int divideTwoNumbers(int first, int second) {
return first / second;
}
public static int minNumberOf(int first, int second) {
return (first < second) ? first : second;
}
public static int maxNumberOf(int first, int second) {
return (first > second) ? first : second;
}
}
최솟값, 최댓값에 대한 마지막 2개 메소드는 static을 적었다.
main() 메소드가 들어 있는 Application7 클래스
public class Application7 {
public static void main(String[] args) {
int first = 100;
int second = 50;
Calculator cal = new Calculator();
int plus = cal.plusTwoNumbers(first, second);
int minus = cal.minusTwoNumbers(first, second);
int multiply = cal.multiplyTwoNumbers(first, second);
int divide = cal.divideTwoNumbers(first, second);
int min = Calculator.minNumberOf(first, second);
int max = Calculator.maxNumberOf(first, second);
System.out.println("두 수의 합 : " + plus);
System.out.println("두 수의 차 : " + minus);
System.out.println("두 수의 곱 : " + multiply);
System.out.println("두 수의 몫 : " + divide);
System.out.println("최솟값 : " + min);
System.out.println("최댓값 : " + max);
}
}
최솟값, 최댓값은 새로 객체에 의존성을 주입해줄 필요없이 Calculator 로 나타낸 것을 알 수 있다.
이것이 static 때문인데 static은 컴퓨터의 고정된 static 메모리 영역에 저장해 기억시킨다.
그래서 non-static 인 메소드는 직접 객체를 의존성 주입을 시켜줘야하지만 static은 이미 메모리에 들어있어 굳이 해줄 필요가 없다.
그럼 무조건적으로 static을 쓰는게 좋은게 아닌가?
그렇지는 않다.
프로그램 실행 시 static이 많으면 부팅하는데 오래 걸린다.
프로그램 종료 시까지 메모리에 할당된 채로 존재한다.
static 영역은 Garbage collector 를 통해 관리를 받지 않아서 악영향을 준다.
객체지향적이지 못하다.
static 영역에 할당돼 있어 여러 클래스들이 데이터를 불러오고, 캡슐화되어야 한다는 객체지향 프로그래밍 원칙을 위반한다.
Interface 를 구현하는데 사용될 수 없다.
코드의 재사용성을 높여주는 객체지향적 기능인 Interface를 사용하는데 방해가 된다.