static int add(int a, int b) { return a + b; }
// │ │ │ └──────┘ 매개변수 목록: 타입 + 이름. 호출 시 순서·타입이 맞아야 함
// │ │ └ 이름: 동사로 시작 (add, print, calculate)
// │ └ 반환 타입: 돌려줄 값의 타입. 없으면 void
// └ 제어자: static이면 객체 없이 클래스 이름으로 호출| 부분 | 역할 | 규칙 |
|---|---|---|
| 반환 타입 | 호출한 쪽에 돌려주는 값의 타입 | void가 아니면 모든 경로에서 return 값; 필수 |
| 이름 | 무엇을 하는지 | 동사(calculate), boolean은 is/has/can |
| 매개변수 | 입력 | 타입과 개수, 순서가 시그니처를 이룸 |
| 본문 | 실제 동작 | 한 가지 일만 |
시그니처(signature)는 "이름 + 매개변수 타입 목록"입니다. add(int, int)와 add(double, double)은 다른 시그니처이고(오버로딩 가능), int add(int, int)와 long add(int, int)는 같은 시그니처입니다(컴파일 오류).
메서드가 호출되면 JVM은 스택(stack)에 그 호출만을 위한 공간, 스택 프레임(stack frame)을 쌓습니다. 프레임에는 매개변수와 지역 변수, 그리고 "끝나면 어디로 돌아갈지"가 들어 있습니다.
static int square(int n) { return n * n; }
static int sumOfSquares(int a, int b) { return square(a) + square(b); }
// main에서 sumOfSquares(3, 4) 호출 시 시간 →
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ │ │ square │ │ │ │ square │
│ │ │ n = 3 │ │ │ │ n = 4 │
├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤
│sumOfSq │ │sumOfSq │ │sumOfSq │ │sumOfSq │
│a=3, b=4 │ │a=3, b=4 │ │a=3, b=4 │ │a=3, b=4 │
├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤
│ main │ │ main │ │ main │ │ main │
└──────────┘ └──────────┘ └──────────┘ └──────────┘return하면 사라집니다(pop). 사라지면 그 안의 지역 변수도 사라집니다.n = 100이라고 해도 호출한 쪽에는 영향이 없습니다. 다른 프레임의 변수이기 때문입니다.StackOverflowError.| 인자 타입 | 복사되는 것 | 메서드 안에서 변경하면 |
|---|---|---|
원시 타입(int, double...) |
값 자체 | 원본 불변 |
| 배열, 객체 | 주소 | a[0] = 9처럼 주소를 따라간 변경은 반영, a = new int[]{} 재대입은 반영 안 됨 |
String |
주소 | String은 불변 객체라 내용 변경 자체가 불가능. 새 문자열을 반환받아야 함 |
"참조 타입은 참조 전달"이 아닙니다. 참조(주소)의 값을 복사하는 것입니다. 04 레슨 2.9와 이어집니다.
같은 이름의 메서드가 여러 개일 때 컴파일러는 다음 순서로 후보를 찾습니다. 한 단계에서 후보가 나오면 다음 단계로 가지 않습니다.
| 단계 | 허용되는 변환 | 예 |
|---|---|---|
| 1 | 정확히 일치 + 확대 원시 변환 | int → long → float → double, char → int |
| 2 | 1단계 + 박싱/언박싱 | int → Integer, Integer → Object |
| 3 | 2단계 + 가변 인자 | call(int...) |
같은 단계에 후보가 둘 이상이면 더 구체적인(specific) 것을 고르고, 우열을 가릴 수 없으면 reference to call is ambiguous 컴파일 오류입니다. call(1)에 call(long)과 call(Integer)가 있다면 1단계에서 long이 뽑히고 Integer는 보지도 않습니다.
메서드가 자기 자신을 호출하는 것입니다. 반드시 두 부분으로 구성됩니다.
| 부분 | 역할 | 빠지면 |
|---|---|---|
| 기저 조건(base case) | 더 이상 호출하지 않고 답을 바로 돌려주는 경우 | 무한 재귀 → StackOverflowError |
| 재귀 단계 | 문제를 조금 작게 만들어 자기 자신 호출 | — |
재귀가 어울리는 문제는 구조 자체가 재귀적인 것(트리, 디렉터리, 중첩된 괄호)입니다. 단순한 반복(팩토리얼, 합계)은 반복문이 더 빠르고 안전합니다. 깊이가 수천을 넘을 수 있으면 반복문으로 바꿉니다.
| 구분 | static | 인스턴스 |
|---|---|---|
| 호출 | MathUtils.clamp(v, 0, 10) |
counter.increment() |
| 상태 | 없음. 입력만으로 결과가 결정 | 객체의 필드에 의존 |
this |
사용 불가 | 사용 가능 |
| 어울리는 것 | 계산, 변환, 검증, 포맷 (유틸리티) | 객체의 상태를 읽거나 바꾸는 행동 |
"입력이 같으면 항상 같은 결과이고 아무 상태도 안 건드린다"면 static입니다. 그 외에는 인스턴스 메서드입니다.