본문 바로가기

코딩/JAVA 공부

[JAVA] 자바의 정석 _ 메서드

 * 메서드란?

메서드: 작업 단위로 문장들을 묶어 이름 붙인 것.

class 안에 있는 함수 = 메서드!

메서드의 장점.

1. 코드의 중복을 줄임

2. 코드의 관리가 쉬움

3. 코드의 재사용 가능

4. 코드가 간결해져 이해가 쉬움

**하나의 메서드는 한 가지 기능만 수행하도록 작성

메서드 = 선언부 + 구현부

선언부 : 반환 타입 메서드 이름 (타입 변수명, 타입 변수명,... (매개변수 (입력)))

구현부 : 메서드 호출 시 수행될 코드

int add (int a, int b){	// 선언부
    int result = a+b;		// 구현부
    return result;		// 구현부
}

리턴 값이 없을 때 반환 타입에 void를 적는다.

 

 * return문

return문 : 실행 중인 메서드를 종료하고 호출한 곳으로 되돌아간다.

반환 타입이 void가 아닌 경우, 반드시 return문 필요.

**메서드 호출 시 반환 값을 담을 변수 type과 메서드의 반환 타입이 일치해야 함.

int result = test.add(3,5);	// okay
double result = test.add(3,5);	// no

	int add(int x, int y){
    	return x + y;
    }

 

 * 호출 스택(call stack)

스택(stack): 및이 막힌 상자. 위에 차곡차곡 쌓임.

호출 스택: 메서드 수행에 필요한 메모리가 제공되는 공간.

메서드는 호출되면 스택에 쌓이고, 맨 위의 메서드 하나만 실행 중이며 나머지는 대기 중.

 

 * 기본형 매개변수 & 참조형 매개변수

- 기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.

- 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다

class Data {int x; }

class Ex{
    public static void main(String[] args){
    	Data d = new Data();
    	d.x = 10;
    
    	change(d.x);
    	// d.x 는 여전히 10
    
    	static void change(int x){  // 매개변수 기본형
    		x = 1000;
    	} // change 끝
    } //main 끝
} //Ex 끝
class Data2 {int x; }

class Ex2{
    public static void main(String[] args){
    	Data2 d = new Data2();
    	d.x = 10;
    
    	change(d);
    	// d.x 1000으로 변경
    
    	static void change(Data2 d){  // 매개변수 참조형
    		d.x = 1000;
    	} // change 끝
    } //main 끝
} //Ex2 끝

매개변수가 기본형이면 단순히 값을 받아오기만 해 변경 불가능.

매개변수가 참조형으로 주면, 객체 안의 iv 주소를 받아올 수 있어 값을 직접 변경 가능.

 

 * 참조형 반환 타입

객체의 주소를 반환한다고 생각.

class Data3 {int x;}

class Ex3{
    public static void main(String[] args){
    Data3 d = new Data3();
    d.x = 10;
    Data3 d2 = copy(d);
    // d.x = 10, d2.x = 10 / 2개의 다른 객체 생성됨.
    
    	static Data3 copy(Data3 k){
    		Data3 tmp = new Data3();
        	tmp.x = k.x;
        	return tmp;
    	}// copy 끝
    }// main 끝
} // Ex3 끝

copy 메서드의 반환 값인 tmp은 Data3 객체의 주소를 가지고 있고, 이를 d2에 넣었음.

d와 d2는 서로 다른 객체.

 

 * static 메서드 & 인스턴스 메서드

메서드 이름 앞에 static 유무에 따라 구분.

인스턴스 메서드

- 인스턴스 생성 후, '참조변수.메소드이름()' 으로 호출

- 인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드

- iv 사용 가능

 

static 메서드

- 객체 생성 없이 '클래스이름.메서드이름()' 으로 호출

- 인스턴스 멤버(iv, im)와 관련 없는 작업을 하는 메서드

- iv 사용 불가 (cv는 사용 가능)

class MyMath{
    long a,b;
    long add(){ // 인스턴스 메서드
    	return a + b;
    }
    static long add(long a, long b){ // static 메서드
    	return a+b;
    }
}//MyMath end


class MyTest{
    public static void main(String[] args){
    	System.out.println(MyMath.add(200l,300l); // 500 , 객체 생성 없이 호출 가능
    	MyMath mm = new MyMath();
    	mm.a = 100l;
    	mm.b = 200l;
	System.out.println(mm.add()); // 300 , 객체 생성해야 호출 가능
	}//main end
}//MyTest end

static을 언제 붙여야 할까?

- 공통 속성 변수에 static을 붙인다.

- 인스턴스 멤버(iv)를 사용하지 않는 메서드에 static을 붙인다.

 

 * 오버 로딩(overloading)

오버 로딩: 한 클래스 안에 같은 이름의 메서드 여러 개 정의하는 것

println의 경우 매개변수의 타입 상관없이 쓸 수 있음. --> 오버 로딩 덕분.

 

오버 로딩이 성립하기 위한 조건

1. 메서드의 이름이 같아야 한다.

2. 매개변수의 개수 또는 타입이 달라야 한다.

3. 반환 타입은 영향 없다. (반환 타입은 동일)

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

// add(3,3) 호출 시 둘 다 가능 --> 에러
// 어떤 메서드 호출하는지 모호해 에러

 * 생성자

생성자 : 클래스와 이름이 동일한 인스턴스 메서드. 객체 생성 시 호출됨.

생성자의 종류

1. 기본 생성자 : 매개변수 없음.

2. 매개변수 있는 생성자 : 매개변수에 넣은 값으로 iv값을 초기화.

클래스엔 적어도 1개의 생성자가 반드시 필요!

생성자가 0개일 때 컴파일러가 자동으로 기본 생성자가 만들어지지만, 1개라도 있으면 자동생성 x

따라서 클래스 작성시 기본 생성자는 반드시 작성 필요!

 

생성자 this() :  같은 클래스의 생성자에서 다른 생성자 호출할 때 사용, 첫 줄에서만 가능

참조 변수 this: 인스턴스 자신을 가리키는 참조 변수. 인스턴스 메서드에서 사용. 지역변수, 인스턴수 변수 구별 위해 사용. (iv, lv의 이름이 같은 경우 구별을 위해)

class Car2{
    String color;
    String gearType;
    int door;
    
    Car2(){
    	this("white", "auto", "4");
    }
    
    Car2()(String color){
    	this(color, "auto", "4");
    }
    
    Car2()(String color, String gearType, int door){
    	this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}//class end

 * 변수의 초기화

- 지역변수

지역변수는 수동 초기화해야 함.(사용 전 꼭!)

멤버 변수(iv, cv)는 자동 초기화된다.

class InitTest{
    int x;
    int y = x; // 인스턴스 변수는 자동 초기화 됨. y=0 대입.
    void method1(){
    	int i;
        int j = i; // 메스드 변수는 자동 초기화 안됨, i 초기화 없이 사용해 에러 발생
    }//method1 end

}//Inittest end

자동 초기화되는 값은 자료형 마다 다르며 아래 표 참고.

자료형 자동 초기화 값
boolean false
char '\u0000'
byte, short, int 0
long 0L
float 0.0f
double 0.0d
참조형 null

- 멤버 변수

멤버 변수 초기화는 몇 가지 방법이 있다.

1. 명시적 초기화 (대입 연산자 '=' 사용)

class Car{
    int door = 4;	     // 기본형 변수 초기화
    Engine e = new Engine(); // 참조형 변수 초기화
}

2. 초기화 블럭

- 인스턴스 변수 초기화 블럭 : {}

- 클래스 변수 초기화 블럭 : static {}

class StaticBlockTest{
    static int[] arr = new int[10];
    
    static{ 									// 클래스 변수 초기화 블럭
    	for(int i=0; i<arr.length; i++){
        	 arr[i] = (int)(Math.random()*10)+1;
    	}//for end
    }//static end
}// StaticBlockTest end

3. 생성자

iv 초기화, 생성자로 객체 생성 시 초기화.

Car(String color, String gearType, int door){
    this color = color;
    this.gearType = gearType;
    this.door = door;
}//Car end

- 클래스 변수 초기화 시점 : 클래스가 처음 메모리에 로딩될 때 1번.

- 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때마다

초기화 순서 : cv --> iv

                     자동 --> 간단 --> 복잡