1. static 선언을 붙여서 선언하는 클래스 변수
- 특정 변수를 공유하고 싶을때
static
을 사용
- 인스턴스 생성과 별개로 하나만 존재하고 어디서나 접근 가능
- 인스턴스 변수 : 인스턴스가 생성될 때 생성
- 클래스 변수 : 클래스 내부에 위치하지만 하나만 존재
- 인스턴스를 생성하지 않아도 특정 메모리 공간에 별도로 저장
class InstCnt {
static int instNum = 0;
InstCnt() {
instNum++;
System.out.println("인스턴스 생성: " + instNum);
}
}
class ClassVar {
public static void main(String[] args) {
InstCnt cnt1 = new InstCnt();
InstCnt cnt2 = new InstCnt();
InstCnt cnt3 = new InstCnt();
}
}
- 클래스 내부 접근
- static 변수가 선언된 클래스 내에서는 이름만으로 직접 접근 가능
- 클래스 외부접근
- private으로 선언되지 않으면 클래스 외부에서 접근 가능 => public
- 클래스 또는 인스턴스의 이름을 통해 접근
class AccessWay {
static int num = 0;
AccessWay() { incrCnt(); }
void incrCnt() {
num++;
}
}
class ClassVarAccess {
public static void main(String[] args) {
AccessWay way = new AccessWay();
way.num++;
AccessWay.num++;
System.out.println("num = " + AccessWay.num);
}
}
- 클래스 변수의 초기화 시점과 초기화 방법
- 생성자 안에서 초기화하면 안됩니다 => 계속 초기화 발생
- JVM => Main 메소드 호출 => 필요한 정보만 읽어드림 ( 유연한 구조 )
- 활용한 클래스만 읽어드림
InstCnt.instNum
을 보고 InstCnt 클래스를 읽음 => static 변수를 캐치 및 메모리 공간에 저장
- 즉 초기화 시점 : JVM이 읽는 순간
class InstCnt {
static int instNum = 100;
InstCnt() {
instNum++;
System.out.println("인스턴스 생성: " + instNum);
}
}
class OnlyClassNoInstance {
public static void main(String[] args) {
InstCnt.instNum -= 15;
System.out.println(InstCnt.instNum);
}
}
- 클래스 변수의 활용
- 인스턴스 별로 가지고 있을 필요가 없는 변수
- 값의 참조가 목적인 변수
- 값의 공유가 목적인 변수
- 그 값이 외부에서 참조하는 값이라면
public
로 선언
2. static 선언을 붙여서 정의하는 클래스 메소드
- 클래스 변수와 성격이 동일
- 다른 메모리 공간에 저장
class NumberPrinter {
private int myNum = 0;
static void showInt(int n) { System.out.println(n); }
static void showDouble(double n) {System.out.println(n); }
void setMyNumber(int n) { myNum = n; }
void showMyNumber() { showInt(myNum); }
}
class ClassMethod {
public static void main(String[] args) {
NumberPrinter.showInt(20);
NumberPrinter np = new NumberPrinter();
np.showDouble(3.15);
np.setMyNumber(75);
np.showMyNumber();
}
}
- 클래스 메소드로 정의하는 것이 옳은 경우
- 단순 기능 제공이 목적인 메소드
- 인스턴스 변수와 관련 지을 이유가 없는 메소드
- 클래스 메소드에서 인스턴스 변수에 접근이 가능할까?
- 불가능 => 다른 공간에 위치하고 있기 때문에...
class AAA {
int num = 0;
static void addNum(int n) {
num += n;
}
}
3. System.out.println 그리고 public static void main()
System.out.println
- System : 클래스
- out : 클래스 변수, 참조변수 ( 다시 점을 찍고 접근하니 )
- println : 인스턴스의 메소드
public statc void main()
- main 메소드는 하나만 존재 => static
- public, void : 자바와 우리의 약속 => 우리가 main을 정의하는데 반환하지말고 public로 선언해줘!
- 외부 (이클립스 등) 툴에서 main 메소드를 실행 => 요청 자체가 클래스 외부에서 이루어지기 때문에...
java.lang.System.out.println(...);
class Car {
void myCar() {
System.out.println("This is my car");
}
public static void main(String[] args) {
Car c = new Car();
c.myCar();
Boat t = new Boat();
t.myBoat();
}
}
class Boat {
void myBoat() {
System.out.println("This is my boat");
}
}
4. 또 다른 용도의 static 선언
- static 초기화 블록
- 선언과 동시에 할당하면 된다.
- 하지만 그 값이 변동성이 있는 것이라면?
class DateOfExecution {
static String date;
static {
LocalDate nDate = LocalDate.now();
date = nDate.toString();
}
public static void main(String[] args) {
System.out.println(date);
}
}
System.out.println(Math.PI);
System.out.println(PI);
참고