클래스 변수 : 클래스가 로드될 때 선언되는 변수, 타입 앞에 static을 붙여 사용한다.
인스턴스 변수 : 인스턴스가 생성될때 선언되는 변수
지역 변수 : 메서드 내에서 선언되며 메서드 종료 시 소멸되는 변수
publicstaticint max; // 클래스 변수publicint max; // 인스턴스 변수publicmethod(){
int m; // 지역 변수
}
1.1.1. 클래스 변수 (class variable)
인스턴스 변수 앞에 static을 추가한다.
한 클래스의 모든 인스턴스들이 공통적인 값을 유지한다.
인스턴스가 생성되지 않아도 사용가능하다.
클래스가 메모리에 로딩될 때 생성되어 프로그램이 종료될 때까지 유지한다.
// 1. 인스턴스 변수 앞에 static을 추가publicint max; // 인스턴스 변수publicstatic max; // 클래스 변수// 2. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지한다.classTv{
publicstaticint max = 100;
}
Tv t1 = new Tv();
Tv t2 = new Tv();
t1.max; // 100
t2.max; // 100// 3. 인스턴스가 생성되지 않아도 사용가능하다.
Tv.max; // 100
1.1.2. 인스턴스 변수 (instance variable)
클래스 영역에 선언한다.
인스턴스 생성할 때 만들어진다.
인스턴스가 생성되어야 컨트롤 가능하다.
public Tv {
publicint max; // 1. 클래스 영역에 선언
}
Tv t = new Tv(); // 2. 인스턴스가 생성이 되어야 변수가 만들어짐
t.max; // 3. 인스턴스가 생성되어야 사용 가능
1.1.3. 지역 변수 (local variable)
메서드 내에서만 선언 가능하다.
메서드 종료 시 소멸된다.
publicset(){
int num = 0; // 1. 메소드 내에서 지역 변수 선언
}
num; // 2. 변수가 선언 되어 있지 않다는 에러
1.2. 클래스 변수와 인스턴스 변수
classCard{
String kind; // 각 인스턴스 고유int num; // 각 인스턴스 고유staticint height = 250; // 모든 인스턴스 공유staticint width = 100; // 모든 인스턴스 공유
}
클래스 변수를 변경 시 모든 인스턴스의 값이 변경된다.
클래스 변수는 "클래스.클래스변수" 형태로 사용하는 것이 좋다. ex) Card.width;
참조 변수를 이용해서 사용할 수 있지만 인스턴스 변수와 혼동이 온다.
클래스 변수는 하나의 저장공간을 갖는다.
2. 메서드
메서드란?
특정 작업을 수행하는 문장들을 하나로 묶은 것이다.
입력과 출력이 있을 수도 있고 없을 수도 있으며 모두 없을 수도 있다.
2.1. 메서드를 사용하는 이유
높은 재사용성 한번 만들어 놓은 메서드들을 변경이고 호출하여 사용할 수 있다.
중복된 코드의 제거 공통된 소스를 하나의 메서드로 만들어 중복된 소스를 줄일 수 있다.
프로그램의 구조화 소스가 많아질수록 가독성이 떨어져 메서드로 작성하여 구조화하면 쉽게 알아볼 수 있다.
위의 예제 중 반복문으로 실행하는 게 더 빠르다. 재귀 호출은 값 복사, 값 반환 등과 같은 작업이 필요하기 때문이다.
그럼에도 재귀 함수를 사용하는 이유는 아래와 같다.
논리적 간결함
비효율적이지만 쉽게 작성
논리적 오류 발생 확률이 낮고 수정이 용이
publicstaticmain(String[] args){
factorial(5);
}
publicintfactorial(int n){
return (n == 1) ? 1 : n * factorial(n-1);
}
publicintfactorial(int n){
int res = 1;
while(n != 0) { // 1번 호출
res *= n--;
}
return res;
}
factorial에 0 또는 100,000 같은 수를 넣으면 스택오버플로우가 발생하며 재귀 호출이 무수히 많이 호출되어 스택이 가득 찬다.
위의 예제 중 가장 아래의 factorial 메서드를 보면 while문으로 작성되어 있다.
재귀 함수로 호출할 경우 factorial을 매번 호출하고 while의 경우 한 번의 호출로 값을 얻을 수 있고 스택오버플로우가 발생하지 않으며 재귀 호출 보다 빠르다.
2.9. 클래스 메서드(static method)와 인스턴스 메서드(instance method)
클래스 변수 : static이 붙은 변수
인스턴스 변수 : static이 붙지 않은 변수
멤버 변수 : 클래스 변수와 인스턴스 변수
멤버 변수 중 모든 인스턴스에 공통으로 사용하면 static을 붙이면 된다.
클래스 변수는 클래스가 메모리에 올라갈 때 생성된다.
클래스 메서드는 인스턴스 변수 사용 불가하다. - 인스턴스 변수는 인스턴스가 존재해야 하므로 클래스 메서드가 사용할 수 없는 경우가 생겨 금지한다. 단, 인스턴스 메서드는 클래스 변수를 사용할 수 있다. 인스턴스가 생성되기 전에 클래스 변수가 생성되어 있어서 가능하다.
메서드 내에서 인스턴스 변수를 사용하지 않는다면 static을 붙이는 것을 고려하자 - 메서드 내에서 인스턴스 변수를 사용하면 static 붙이는 게 불가능하다. 하지만 인스턴스 변수를 사용하지 않는다면 static을 붙여 미리 로드시켜 놓으면 인스턴스 생성 시 호출되어야 할 메서드를 찾는 과정이 줄어들면서 성능이 향상된다.
3. 클래스 멤버와 인스턴스 멤버 간의 참조와 호출
멤버 종류
클래스 멤버
인스턴스 멤버
인스턴스 변수
X
O
인스턴스 메서드
X
O
클래스 변수
O
O
클래스 메서드
O
O
단, 인스턴스 멤버를 사용하기 위해서 인스턴스를 생성해야 한다.
인스턴스 멤버와 클래스 멤버 간의 존재 시점이 다르기 때문에 참조와 호출이 불가능할 수 있다.
만약 인스턴스 멤버와 클래스 멤버가 참조, 호출이 되고 있다면 클래스 멤버를 잘못 사용한 것은 아닌지 확인해 볼 필요가 있다.