[작성일: 2023. 01. 25]
메서드(Method)
public static void main(String[] args){}
접근제한자 [static] 리턴타입 메서드명 (매개변수...)
- 작업을 수행하기 위한 명령문의 집합으로 어떤 값을 입력받아서 처리하고 그 결과를 돌려줌. (입력받는 값이 없을 수도 있고 결과를 돌려주지 않을 수도 있음.)
- {문장들}을 작업단위로 묶어서 이름을 붙인 것을 메서드라고 함.
- 값(입력)을 받아서 처리하고 결과를 반환(출력)
- 반환타입: 0~1개, 없을 수도 있고 많아야 1개.
- 2개 이사일 경우 배열 혹은 객체로 묶어서 반환
- 반환타입이 없을 경우 void 사용하면 됨
- 메서드 이름
- 매개변수: 0~n개 입력 가능, 없을 수도 있음
메서드 = 선언부 + 구현부 반환타입(출력) 메서드이름 매개변수 입력값(타입 변수명1, 2 ...) int add(int x, int y) { // 선언부 int result = x + y; // 구현부 return result; //결과 반환 }
메서드의 장점과 작성지침
- 반복적인 코드를 줄이고 코드의 관리가 용이함.
- 반복적으로 수행되는 여러 문장을 메서드로 작성
- 하나의 메서드는 하나의 기능만 수행하도록 작성(유지보수 및 재사용성을 위해)
- 관련된 여러 문장을 메서드로 작성
- 클래스 영역에서만 정의할 수 있음.
public static void main(String args[]){
for(int i=0; i<10; i++)
numArr[i] = (int)(Math.random()*10);
for(int i=0; i<10; i++)
System.out.printf("%d", numArr[i]);
System.out.println();
...(생략)
for(int i=0; i<10; i++)
System.out.printf("%d", numArr[i];)
System.out.println();
// 코드 중복이 있어서 좋지 않은 코드
}
⬇
static void printArr(int[] numArr) { // 메서드 이름 정의
for(int i=0; i<10; i++)
System.out.printf("%d", numArr[i]);
System.out.println();
}
public static void main(String[] args) {
...(생략)
for(int i=0; i<10; i++)
numArr[i] = (int)(Math.random() * 10);
printArr(numArr); // 배열 출력
...중간 생략... // 메서드 호출(사용)
printArr(numArr); // 배열 출력
}
메서드의 호출
- 클래스 작성
- 객체(인스턴스) 생성
- 메서드 사용(호출)
- main 메서드에서 메서드 add를 호출
- 메서드 add의 괄호{}안에 있는 문장들이 매개변수에 복사되어 메서드의 첫 문장부터 순서대로 수행됨.
- 메서드 add의 모든 문장이 실행되거나 return문을 만나면 호출한 메서드(main 메서드)로 결과값을 가지고 되돌아와서 이후의 문장들을 실행함.
package Ex;
class Ex6_4 {
public static void main(String args[]) {
MyMath mm = new MyMath();
long result1 = mm.add(5L, 3L); // add 메서드 호출
long result2 = mm.subtract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);
System.out.println("add(5L, 3L) = " + result1);
System.out.println("subtract(5L, 3L) = " + result2);
System.out.println("multiply(5L, 3L) = " + result3);
System.out.println("divide(5L, 3L) = " + result4);
}
}
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(double a, double b) { return a / b; }
}
응용
// 두 값을 받아서 둘 중에 큰 값을 반환하는 메서드를 작성하시오.
int max(int a, int b) {
int result = 0;
if(a>b) {
result = a;
} else {
result = b;
}
return result;
}
// 두 값을 받아서 둘 중에 작은 값을 반환하는 메서드를 작성하시오.
long min(long a, long b) {
return a > b ? b : a;
}
return문
- 실행 중인 메서드를 종료하고 호출한 곳으로 되돌아감
void printGugudan(int dan) {
if(!(2 <= dan && dan <= 9))
return; // dan이 2와 9 사이가 아니면 호출한 곳으로 리턴
for(int i=1; i<=9; i++) {
System.out.printf("%d * %d = %d%n", dan, i, dan*i);
//return;
// 메서드가 작업을 마쳤을 때 리턴문을 적어줘야 하지만
// 반환 타입이 void일 때는 생략가능(컴파일러 자동추가)
}
}
- 반환타입이 void가 아닌 경우, 반드시 return문 필요
int multiply(int x, int y) {
int result = x * y;
return result; // 반환타입이 void가 아니므로 생략불가
int max(int a, int b) {
if( a > b)
return a; // 조건식이 참일 때만 실행
// 거짓일 때는 return문이 없기 때문에 에러
- 메서드가 정상적으로 종료되는 경우 현재 실행중인 메서드를 종료하고 호출한 메서드로 되돌아 감
- 메서드의 블럭{}의 끝에 도달했을 때
- 메서드의 블럭{}을 수행 도중 return문을 만났을 때
- 반환타입이 일치해야 함.(자동형변환 되는 경우 제외)
- 반환값이 있는 메서드는 모든 경우에 return문이 있어야 함
int add(int x, int y) {
int result = x + y;
return result;
}
⬇
int add(int x, int y) {
return x + y;
}
- return문을 적절히 사용하면 코드가 간결해짐.
static 메서드
- 클래스 메서드
- 객체생성 없이 '클래스이름.메서드이름()'으로 호출
- 인스턴스 멤버(iv, im)와 관련 없는 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 불가
- Math.random(), Math.round()
- 작업에 필요한 값을 매개변수(lv)로 받음
인스턴스 메서드
- 인스턴스 생성 후 '참조변수.메서드이름()'으로 호출
- 인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
- 메서드 내에서 인스턴스 변수(iv) 사용 가능
- 입력값(매개변수)가 없기 때문에 iv값 사용해야 함
class MyMath2 {
long a, b; // iv (인스턴스 변수-클래스 전체에서 사용가능)
long add() { // 인스턴스 메서드
return a + b; // iv
static long add(long a, long b) {
// static 메서드, lv(지역변수 - 메서드 종료될 때 까지만 유효
return a + b; // 지역변수(가까운 쪽 변수)
}
}
class MyMathTest2 {
public static void main(String[] args[]) {
System.out.println(MyMath2.add(200L, 100L);
// 클래스 메서드 호출 <클래스이름.메서드이름>
// 객체 생성없이 호출 가능
// 객체를 안 만들어서 참조변수가 없음
MyMath2 mm = new MyMath2(); // 인스턴스 생성
mm.a = 200L;
mm.b = 100L;
System.out.println(mm.add());
// 인스턴스 메서드 호출 <참조변수.메서드이름>
// 객체생성 후 메서드 호출할 수 있음
}
}
static을 언제 붙여야 할까?
- 속성(멤버 변수) 중에서 공통 속성에 static 붙임.
- 인스턴스 멤버(iv, im)를 사용하지 않는 메서드에 static 붙임.
1.
class Card {
String kind;
int number; // 개별속성
static int width = 100;
static int height = 250; // 공통속성
2.
class MaMath2 {
long a, b; // iv
long add() // 인스턴스 메서드
{ return a + b; } // 인스턴스 변수
static long add(long a, long b) // static 메서드
{ return a + b; } // 지역 변수
메서드 간의 호출과 참조
- static 메서드는 인스턴스 변수(iv)를 사용할 수 없음.
class TestClass2 {
int iv; // 인스턴스 변수, 객체 생성 후 사용 가능
static int cv; // 클래스 변수, 언제나 사용 가능
void instanceMethod() { // 인스턴스 메서드
System.out.println(iv); // 인스턴스 변수 사용 가능
System.out.println(cv);
// 클래스 변수 사용 가능, 언제든 사용 가능하니까!
}
static void staticMethod() { // static 메서드
System.out.println(iv); // 에러. 인스턴스 변수 사용 불가
System.out.println(cv); // 클래스 변수 사용 가능
}
} // end of class
- static 메서드는 인스턴스 메서드(im)를 호출할 수 없음.
class TestClass {
void instanceMethod() {} // 인스턴스 메서드
static void staticMethod() {} // static 메서드
void instanceMethod2() { // 인스턴스 메서드
instanceMethod(); // 다른 인스턴스 메서드 호출 가능
staticMethod(); // static 메서드 호출 가능
}
static void staticMethod2() { // static 메서드
instanceMethod(); // 에러. 인스턴스 메서드 호출 불가능
staticMethod(); // static 메서드 호출 가능
}
} // end of class
Q&A
Q. static 메서드는 static 메서드 호출 가능할까?
A. 가능
Q. static 메서드는 인스턴스 변수 사용 가능할까?
A. 불가능(객체 생성해야 iv를 사용할 수 있기 때문)
Q. static 메서드는 인스턴스 메서드 호출이 가능할까?
A. 불가능(iv로 작업하기 때문)
Q. 왜 static 메서드는 인스턴스 멤버를 쓸 수 없을까?
A. static 메서드 호출 시 객체가 없을 수도 있기 때문
🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.